THE BNL CROSS ASSEMBLER FOR THE SSP USER'S GUIDE Version 5.10 R. Hackenburg Brookhaven National Laboratory MPS Group September 27, 1989 Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . 1 2. Cross Assembler Statements . . . . . . . . . . . . . 3 2.1 Control Statements . . . . . . . . . . . . . . 3 2.2 Data Statements . . . . . . . . . . . . . . . 10 2.3 Instruction Statements . . . . . . . . . . . . 12 2.3.1 BNL MACRO Instructions . . . . . . . . . 13 2.4 Cross Assembler Control Symbols . . . . . . . 16 3. Invoking the Cross Assembler and Linker . . . . . . 18 4. The BNL System for the SSP - BNLSYS . . . . . . . . 22 5. The Buffered Segment Interconnect - BSI . . . . . . 27 6. The BNL System Subroutines for the SSP . . . . . . . 28 6.1 64-Bit Integer Arithmetic Routines . . . . . . . 32 6.2 Floating-point Arithmetic Routines . . . . . . . 34 7. Programming Techniques . . . . . . . . . . . . . . . 38 7.1 Notes on Operand Specification . . . . . . . . 38 7.2 Remarks on FASTBUS I/O Instructions . . . . . 39 7.3 Notes on Addressing . . . . . . . . . . . . . . 41 7.4 Miscellaneous Notes . . . . . . . . . . . . . . 46 8. Debugging Techniques . . . . . . . . . . . . . . . . 47 8.1 Debugging Tools . . . . . . . . . . . . . . . 48 References . . . . . . . . . . . . . . . . . . . . . . . 53 Appendices A. Cross Assembler Error Messages . . . . . . . . . . . A-1 B. System Error and Halt-Codes . . . . . . . . . . . . B-1 Error-Codes . . . . . . . . . . . . . . . . . . . . B-1 Halt-Codes . . . . . . . . . . . . . . . . . . . . . B-4 BSI Return-Codes . . . . . . . . . . . . . . . . . . B-4 C. Coding Sample . . . . . . . . . . . . . . . . . . . C-1 D. Assembler Listing Sample . . . . . . . . . . . . . D-1 E. Link Map Sample . . . . . . . . . . . . . . . . . . E-1 F. CSR0, CSR8 and the PSW . . . . . . . . . . . . . . . F-1 G. The SLAC Instruction Set . . . . . . . . . . . . . G-1 IBM-Like Instructions . . . . . . . . . . . . . G-1 SSP-Specific and FASTBUS I/O Instructions . . . G-4 H. SSP Opcodes . . . . . . . . . . . . . . . . . . . . H-1 I. BNL Instruction Macro Summary . . . . . . . . . . . I-1 J. Differences Between the BNL Cross Assembler and IBM J-1 K. Macro Summary . . . . . . . . . . . . . . . . . . . K-1 (This manual exists as the file BNL$SSP:SSP_PROGRAMMER.MEM) Page 1 Section 1 Introduction The SSP (SLAC Scanner Processor) is a FASTBUS-based CPU with full bus-mastership capability, and may also function as a slave to other FASTBUS masters. The SSP is downloaded with instructions (up to 4096) and data (512 Kbytes) from a host computer via some other FASTBUS master which acts as the computer-to-FASTBUS interface. The SSP itself has no I/O capability other than FASTBUS, and two front-panel signal ports. One of these signals is output by the SSP and is used in synchronizing electronics with the SSP, while the other is used to start the SSP's CPU. The SSP's non-FASTBUS instruction set closely ressembles the integer instruction subset of the IBM 360/370 mainframes; the SSP contains no floating point hardware. The SSP's memory is physically divided into two parts: Data Memory (DM) and Program Memory (PM). PM contains only SSP CPU instructions. DM contains data used by the CPU instructions, as well as data written to or read from FASTBUS. This division of SSP memory into DM and PM represents a major deviation from the IBM 360/370, and must be dealt with by any assembler which produces code for the SSP. Another significant difference is the size of the instructions. IBM instructions may be one to six bytes long, whereas SSP instructions are all four bytes long. Short instructions are padded with zeros to make them four bytes long; long instructions (over 4 bytes) do not exist. There are also some subtle differences in the way index and base registers are used. At SLAC, code for the SSP is written in IBM assembler language, then assembled using the IBM assembler, together with a macro library which defines the FASTBUS instructions. The resulting assembled object code is then run through a linker-translator which modifies the code as required by the differences in the SSP and the IBM mainframes. Some code at SLAC is also written in FORTRAN for the SSP, the resulting object code again being submitted to a linker-translator for correction - no floating point operations are allowed. Not all potential users of the SSP have easy access to a mainframe IBM, however. The BNL cross assembler consists of a macro library, used with the VAX-11 MACRO assembler, and generates object files from source files. SSP instructions are formed by the cross assembler with .LONG directives. The programmer who is not familiar with VAX-11 MACRO is refered to the VAX-11 MACRO Language Reference Manual. The macros have been designed to resemble the IBM format, and it is generally possible to convert code written for assembly on an IBM mainframe into code for assembly on a VAX without much Page 2 effort. Besides the set of IBM and FASTBUS I/O instructions contained in the library, there are also some higher level macro definitions which facilitate such things as data definition, subroutine linkage and repetitive loops. This cross assembler produces SSP machine code that is in separated form (SSP program memory and data memory are two different entities). The object files produced by the cross assembler are linked together with the VAX linker to form SSP-executable files, which are downloaded into SSPs and executed. Downloading and many other functions are performed with a FORTRAN subroutine library of SSP access routines, described in detail in the manual "BNL Access Routines for the SSP User's Guide", found in the file SSPAR.MEM (ref. 1). The BNL cross assembler has built into it a number of checks, error messages and warnings, with the idea being that actual VAX-11 MACRO error messages should be encountered rarely, if at all, by anyone with a vague idea of how to use the VAX-11 MACRO assembler. This is an important feature, since a VAX-11 MACRO error message will contain little, if any, information pertaining to how to fix a problem encountered by the BNL Cross Assembler. Section 7, Programming Techniques, and section 8, Debugging Techniques, should be thoroughly read by anyone who intends to write SSP programs. Appendix J contains a brief summary of the differences between the use of the BNL cross assembler and the IBM assembler. Page 3 Section 2 Cross Assembler Statements Cross assembler statements fall into three major catagories - instruction statements, data statements and control statements. After assembling, linking and loading, instruction statements produce code that is loaded into the SSP's program memory (PM), while data statements produce code that is loaded into the SSP's data memory (DM). This is accomplished through the use of PSECTs, which permit the assembler to produce "separated" code (DM and PM are separated from each other). Control statements may produce both kinds of code, or none at all. These statements obey the VAX-11 MACRO rules: a label field, normally starting in column 1 and always terminated by one or two colons; one or more spaces or tabs, followed by the statement name itself; one or more spaces or tabs, followed by the statement's arguments, separated from each other by spaces, tabs or commas. A semicolon placed anywhere on a line indicates that all remaining characters on that line form a comment. Note on Register Usage The programmer is cautioned about the use of registers 1, 13, 14 and 15, since these are used by the BNL cross assembler for setting up subroutine calls, and by the breakpoint handler in setting up breakpoints. Register 13 also serves as the implied base register when a routine begins execution. Modifying these registers may cause unpredictable results. Register 0 is generally available as a "scratch" register, but its use should be avoided unless the programmer is certain that no "hidden" use is being made of register 0, such as occurs with the INCR and DECR macros. A summary of the BNL cross assembler macros appears in appendix K. Section 2.1 Control Statements Control statements make no assumption about which is the current PSECT and leave PSECT PM in effect when the control statement is done. Exceptions to that are the END, USING and DROP statements, which do nothing with PSECTs and generate no code, and the FIXED_DATA statement, which leaves PSECT DM in effect. Page 4 1. CALL name,arg1,arg2,...arg16 This causes program control to transfer to subroutine "name", starting at PM location "name", and with register 15 being loaded with the value "$name", which is the DM base address of the called subroutine. Up to 16 arguments, "arg1,arg2,...arg16" may be specified. If arguments are specified, they are passed according to standard protocol: register 1 is set to point to an area in DM created by the CALL macro with the first word containing the number of arguments (unless there are no arguments). Each of the words following the first word points to an argument. See Appendix C for an example of passing arguments with the CALL macro. Upon entry into the subroutine, register 13 is loaded with the contents of register 15 (after register 13 is saved; this value must be restored upon leaving the subroutine since it will then continue to serve as base register for the calling routine), and register 13 is then used by the subroutine as its implied base register. 2. FIXED_DATA name FIXED_DATA defines an area of DM which will not "belong" to any subroutine or to the main routine, and which, if properly linked with other object modules, will always reside at the same absolute location in DM address space. The FIXED_DATA statement is used similarly to a SUBROUTINE or PROGRAM statement; DM locations are defined within a "FIXED_DATA" with the usual data statements. "name" isn't used for anything, except that a marker (see the MARKER statement) of this name is created, showing the absolute DM address of the start of the DM area created with the FIXED_DATA statement. PM statements (instructions) may not be used inside a FIXED_DATA. Locations should be defined as global, either with a double colon or double equal-sign, or even with the .GLOBAL directive; these locations may then be referenced externally, by other modules (i.e., subroutines and the main program). Object modules should be linked so that DM addresses defined in a FIXED_DATA area all fall in the low 4K bytes of DM; locations defined in a FIXED_DATA should be referenced without base registers. Large arrays (such as data buffers) ought not to be defined in a FIXED_DATA; there are other, better ways of defining buffers such that all routines have access to them. See section 7.3, Notes on Adressing, for an explanation of how to define large data arrays and buffers; see Appendix C for an example. Page 5 3. DIAGNOSTIC name,start,buffer,nwords,expect,title This is a special-purpose control statement, designed to facilitate the writing of SSP diagnostics, and meant to be used with the CHECK program (see "BNL Access Routines for the SSP User's Guide", found in SSPAR.MEM), which loads and executes SSP diagnostics. SSP diagnostics are cross-assembled in the usual way (see the section "Invoking The Cross Assembler and Linker"), but are linked with the base-line system BNLBAS, instead of the full system, BNLSYS. These diagnostics are downloaded into the SSP by CHECK, after the SSP's program memory and data memory have first been checked for read/write integrity (by CHECK). Any number of diagnostics may be included in one file, but each should end with a HALT instruction and an END statement. Each of the parameters specified in the DIAGNOSTIC statement, except for the "name" parameter, is loaded into an entry of a linked list in the SSP's DM, and is read and used by CHECK. "name" is a name given to the diagnostic, and is useful only for the purpose of looking at a VAX-11 MACRO listing. "start" is the starting address in the SSP's PM of the diagnostic. Note that it is the programmer's responsibility to HALT each and every diagnostic by programming in a HALT instruction statement, or else one diagnostic may simply run on into the next. CHECK expects to run each diagnostic separately by reading the value "start" from the SSP, writing it to DM 0, then starting the SSP. "buffer" is the address of the DM buffer that will contain one or more result-words. "nwords" is the number of words in "buffer". "expect" is the address of a DM buffer which contains the exact contents that "buffer" should contain, if the diagnostic is successful. "title" is an ASCII string, delimited by angle brackets "<" and ">", which will be stored in the SSP and read out and displayed when the diagnostic is executed. "title" ought to be a brief description of the diagnostic. 4. DM This sets the current PSECT to DM. When the DM Page 6 statement is used, the PM control statement must be used before the next instruction statement. 5. DO index,low,high,step This closely resembles the FORTRAN-77 (unlabelled) DO statement; the "=" is replaced with a "," (the main difference). "index" is a DM location, unless it is a number from 0 to 15, inclusive, in which case it is assumed to be a register. "low", "high" and "step" may each (independently) be one of the following: 1. DM locations, locally defined (DM locations defined externally, such as in a FIXED_DATA, will not work), 2. Absolute expressions (purely numerical), in which case DM locations are allocated and defined to have the contents indicated by the numerical expression, 3. blank, in which case the default values low=0, high=0, step=1 will be used. When program control reaches the DO statement, the index is initialized with the contents of DM location (or the numerical value) "low", then the step size, which is the contents of DM location or the numerical value "step" is subtracted from the index. The step size is next added back to the index and the index is compared with the contents of DM location or the numerical value "high". If the index compares high, then program control transfers to the statement following the ENDDO statement corresponding to this DO statement. If the index compares low or equal, program control proceeds to the next instruction following the DO statement. DO loops may be nested to essentially any level. 6. DROP reg1,reg2,...reg16 This allows the programmer to discontinue up to 16 registers from being used as implied base registers. An error will result if an attempt to DROP a register that has not been declared in a USING statement is made. 7. END This defines the end of a routine and should not be confused with the DEC ".END" directive, which should not be used by the programmer since it is automatically "inserted" when the cross assembler is invoked. Page 7 8. ENDDO or END DO When program control reaches this statement, it transfers back to the corresponding DO statement, where the index is incremented and compared, and a decision is made whether to continue the loop or exit it. 9. MARKER symbol,title,indentation This sets up a block of data in PSECT MARKER called a "marker block". Data produced by the MARKER control statement does not in any way affect the execution of the SSP code by the SSP, and the option exists to not download markers into the SSP. See "BNL Access Routines for the SSP User's Guide" (found in SSPAR.MEM), subroutine DOWN, for more details. Marker blocks are used by host-resident software to identify the PM and DM (and "virtual" DM, if selected) base addresses of each of the software modules (subroutines, etc.) resident in the SSP. This information is used in turn to provide symbolic access to internal SSP memory locations. Marker blocks consist of a word which contains the value of "symbol", and an ASCII text string "title", which must be enclosed in angle brackets "<" and ">", and which may contain no backslashes "\". If the "title" argument is not specified, "symbol" is used as if it had been specified both as the "symbol" and "title" arguments. The subroutine SHOW (qv. ref. 1, sect. 2.2), or the SSPAR command "SHOW MARKERS" (qv ref. 1, sect. 1.1), will list all blocks created with the MARKER statement, indenting the title from the left by an amount specified by the optional "indentation" argument, which defaults to zero. For more information on the use of markers, see the SSPAR command "SHOW MARKER" in "BNL Access Routines for the SSP User's Guide", found in SSPAR.MEM (ref. 1). 10. PM This sets the current PSECT to PM, and is only necessary if the DM statement or the .PSECT directive has been used. 11. PROGRAM name This defines the beginning of the main program, called "name". Several internal counters and symbols are defined by this statement, a register save area is defined and register 13 is set up to point at that register-save area. Register 13 is also declared as the base register. Page 8 12. RETURN This statement restores registers from the subroutine's register save area and returns control to the calling routine. 13. SUBROUTINE name This defines the beginning of subroutine "name". Registers are saved (see the control symbols $RSAV0 and $RSAVL, section 2.4) in the calling routine's register save area, a register-save area for this subroutine is reserved and register 13 is declared to be the implied base register; the SUBROUTINE statement takes care of subroutine-calling protocol in a fashion that is both transparent to the programmer and permits nesting subroutine calls essentially without limit. Arguments may be passed through global locations, registers or by an argument pointer list, as set up by the CALL macro; see Appendix C for an example using such an argument pointer list. The global symbol "name" is set to have the PM address of the first instruction in the subroutine, and "$name" is set to have the DM address of the subroutine's lowest DM location, which is the register save area. Note on defining multiple subroutines in one file The VAX-11 MACRO assembler does not recognize the SUBROUTINE statement as meaning anything special. A symbol, once defined somewhere in a source file, remains defined throughout the assembly of that file, even across subroutine boundries. Therefore, some care must be exercised not to use the same symbol name in two or more routines contained in the same file. This problem vanishes if the routines are contained in separate files and assembled separately, which is the recommended practice. Note on subroutine argument passing While the CALL statement facilitates argument passing, there is no such facilitation with the SUBROUTINE statement; it is up to the programmer to understand and make proper use of the argument pointer list created by the CALL macro (see Appendix C). Page 9 14. SYSTEM "name" This is used to write SSP systems. In order to handle errors and interrupts, there must be an error/interrupt handler resident in the SSP whenever a program is executed. Also, some macros, such as HALT, DMPREG, CALL, etc., require that certain locations in low DM either contain specific data, or are free for their exclusive use. It is the system which provides these features; when an SSP program is linked, an SSP system must always be linked with it. See sections 3 and 4. See also the control symbol $LMARK, in section 2.4 15. USING loc,reg1,reg2,...reg16 Declares up to 16 registers to be used as implied base registers. "loc" is a relocatable value. This statement tells the cross assembler that "reg1" will contain the value "loc", "reg2" will contain "loc"+4096, "reg3" will contain "loc"+8192, etc. The cross assembler will then use these registers as implicit base registers whenever an operand so warrants. It is the programmer's responsibility to actually load, during run-time, the specified registers with the specified values; the USING statement doesn't actually load any registers. Note that register 0 may never be used as a base or index register, though it may be declared as such. Declaring register 0 as an implied base register with a USING statement (with "loc" being zero) has the effect of not using any base registers on DM locations that are in the first 4K of DM. This should only be done if those DM locations will never get relocated beyond the first 4K of DM, as is the case in resident SSP systems. If proper use of the PROGRAM, SUBROUTINE, FIXED_DATA and VIRTUAL statements is made, then it is unlikely that the programmer will ever need to actually use the USING statement. The programmer who makes use of the USING statement will, almost without exception, find that there is a better way of doing the same thing without worrying about base registers (and USING statements), given a better understanding of this cross assembler and programming with it. There are subtleties in the useage of base registers, and they will in general not be grasped without some effort. Read Appendix J, Differences Between the BNL Cross Assembler and IBM, item 7, and section 7.3, Notes on Adressing. See also Appendix C, the coding sample. Page 10 Section 2.2 Data Statements Data statements come in two categories, "IBM-Like" and "Higher-Level" data statements. "IBM-Like" Data Statements These data statements must be preceded with the DM control statement (see the DM and PM control statements). 1. DC val1,...val10 Define Constant - defines up to 10 (sequential) DM locations, to be initially loaded with the values val1,...val10. Since "DC" is translated directly into the VAX-11 MACRO ".LONG" directive, it is recommended that ".LONG" be used instead of DC; this will result in slightly faster cross-assembling. 2. DS nwords Define Storage - reserves "nwords" words of SSP DM. This is equivalent to the ".BLKL" directive. PM Address Data Statements These data statements are used specifically for PM addresses, such as the address of a subroutine or branch destination; see section 7.3, Notes on Addressing. PM address statements must be preceded with the DM control statement (see the DM and PM control statements). 1. .PMADDR val1,...val10 Program Memory Address - special version of VAX-11 MACRO .ADDR or .LONG directives which defines up to 10 (sequential) DM locations containing PM addresses, initially loaded with the values </4>,...</4>, where $P0 is the "base" address for the PM PSECT. This statement must be used when defining DM locations which contain PM addresses because of the way the cross assembler separates DM from PM. See the section "Invoking the Cross Assembler and Linker" for a fuller explanation of the DM and PM separation. Note that .ADDR and .LONG produce equivalent results with the BNL cross assembler. .PMADDR is equivalent to DCPM. Page 11 2. DCPM val1,...val10 See .PMADDR, which is equivalent to DCPM. "Higher-Level" Data Statements These data statements need not be preceded by the DM control statement. Each of these statements invokes the DM macro, then restores the previously-in-effect PSECT when done. 1. DATA name1/val1/,name2/val2/,.../name10/val10/ Defines up to 10 (sequential) DM locations, labelled name1,name2,...name10 and initially containing val1,val2,...val10. The commas are needed. The DATA statement cannot be used on previously defined locations, nor can it be used in conjunction with the DIMENSION or VIRTUAL statements. In particular, FORTRAN-like usage of data statements with dimensioned arrays is verboten: DATA NAME/3*17/ would not be permitted. 2. DIMENSION name1(len1),...name10(len10) Defines up to 10 (sequential) "areas" of DM labelled name1,...name10 of sizes (in words) len1,...len10. The symbols $DIM_name1,... $DIM_name10 are automatically defined to have the values len1,...len10. The DIMENSION statement ought not to be used to define large data arrays or buffers; use the VIRTUAL statement instead (or else base register usage may be greatly complicated). 3. VIRTUAL name1(len1),...name10(len10) Used the same as the DIMENSION statement (including the automatic definition of $DIM_name1, etc.), this reserves SSP DM in a fashion different from the DIMENSION statement. "VIRTUAL" DM is reserved at load time after all non-"VIRTUAL" memory definitions have been made. See section 7.3, Notes on Addressing. Page 12 Section 2.3 Instruction Statements The current PSECT should be PM. If the DM statement has been used, then instruction statements must be preceded with the PM statement, or else they will be loaded into DM, not PM. Instruction statements are assembled into single PM words of 32 bits each. They are used in the VAX-11 MACRO standard format: label: opcode-mnemonic operands "label" is assigned the current value of the PM location counter; the colon is required (a double colon causes "label" to be global). "opcode-mnemonic" is one of mnemonics for an SSP opcode, and is actually the name of a macro defined in the BNL cross assembler library. The permitted opcodes may be found in Appendix H as well as in the SSP hardware documents (from SLAC) and IBM machine instruction documents (a good text which explains in some detail the IBM machine instructions is a book by George Strubble - "Assembler Language Programming: The IBM System/360", published by Addison-Wesley). The operands are expressed in one of the IBM standard forms, the choice being determined by the opcode. Appendix G describes the exact usage of operands with each of the instruction statement macros defined in the BNL macro library for the SSP. The operand forms relevant to the SSP are listed below: 1. RR Register-Register Two operands, both registers, are specified. The operands themselves are absolute expressions or symbols with values between 0 and 15 (inclusive). Instructions with operands in this format actually use only 16 bits out of a 32 bit PM word, but since the SSP (unlike a true IBM machine) cannot address PM by the byte, the remaining 16 bits are padded with zeroes and are otherwise unused. 2. RX Register-Index,Base,Displacement Two operands, the first a register, specified as in the RR case; the second is the address of either a DM or a PM word. This address may be represented in several ways which ultimately get converted by the assembler into the form X,B,D, where X is an index register, B is a base register, and D is a 12-bit displacement. The address of the operand is computed as the sum of the contents of register X and register B, and the displacement D. If zero is used as register X or B, Page 13 then the value zero is used directly in the address computation, instead of the contents of register 0. See section 7.1, Notes on Operand Specification, for more details about implicit and explicit addressing. 3. RS Register-Base,Displacement Three operands, the first two registers, specified as in the RR case; the third is the address of a DM or a PM word. This address is specified in the same way as in the RX case, except that there is no index (X) field. Some instructions with operands in the RS format do not actually use both register operands; the second may be ignored (see Appendix G). 4. SI Base,Displacement-Immediate value Two operands, the first a DM or PM address, expressed as in the RS case. The second operand is an "immediate" value - a one byte integer (8 bits). Some instructions ignore the second operand (see Appendix G). Section 2.3.1 BNL MACRO Instructions In addition to the IBM and FASTBUS I/O instruction statements, some composite or special instructions also exist. These are: 1. CLIL S,I Longword version of CLI. See TML for complete description. 2. DECR S Decrements operand "S" by one; expands into a load, subtract, store sequence. DECR uses BNLSYS location $1SYS as the source of the one, and uses register 0 to do the arithmetic; hence, register 0 is destroyed by DECR. 3. DMPREG Dumps all 16 registers in the system register dump area, starting at BNLSYS location $RDUMP. Page 14 4. HALT Halts the processor by writing the contents of BNLSYS location $HALT to CSR0. 5. INCR S Increments operand "S" by one; expands into a load, add, store sequence. INCR uses BNLSYS location $1SYS as the source of the one, and uses register 0 to do the arithmetic; hence, register 0 is destroyed by INCR. 6. INT_OFF Disables Interrupts by clearing the system mask bit in the PSW. 7. INT_ON Enables Interrupts by setting the system mask bit in the PSW. 8. LAPM R,S PM version of the LA instruction. This instruction is especially important to programmers who wish to load a PM address into a register for any purpose. 9. MVIL S,I Longword version of MVI. See TML for complete description. 10. NIL S,I Longword version of NI. See TML for complete description. 11. OIL S,I Longword version of OI. See TML for complete description. 12. PAUSE "Soft-halts" the processor by writing the contents of BNLSYS location $PAUSE to CSR0 (see Appendix F). The SSP resumes execution of code, following a PAUSE, when either bit 11 in CSR0 (see appendix F) is written to by another FASTBUS master or a pulse is delivered to the front-panel START port. Page 15 13. TML S,I Longword version of TM. TML is the same as TM, except that for non-zero I the cross-assembler decides whether to add 3, 2, 1 or nothing to S, depending on the size of I, and byte-shifts I down (by shifting low bytes off) until it is between 1 and 255. For no shifts, 3 is added to S; for 1 shift, 2 is added to S; for 2 shifts, 1 is added to S; for 3 shifts, nothing is added to S. The TML is mainly intended for applications where only one bit is being tested, in which case it always behaves as a true longword version of TM. All of the immediate-value instructions have equivalent longword versions which are converted to the corresponding byte instruction in the same fashion as TML is converted to TM. While TML results in a TM instruction, and therefore works on only one byte (it is not a true Test under Mask, longword, instruction), it gives the appearance (and associated ease of use) that it works on longwords instead of bytes. It obviates the need to manually add a 1, 2 or 3 to S if the high-order byte is not the one being used. Remember that S+3 refers to the low order byte in the SSP, unlike a VAX. Examples: TML A,<^X40> is equivalent to: TM A+3,<^X40> TML A,<^X800> is equivalent to: TM A+2,<^X8> TML A,<^X020000> is equivalent to: TM A+1,<^X2> TML A,<^XF0100076> is equivalent to: TM A,<^XF0> (note that only the high-order byte of the immediate value is used.) 14. XIL S,I Longword version of XI. See TML for complete description. Page 16 Section 2.4 Cross Assembler Control Symbols There are several symbols that can be changed by the programmer for various effects during assembly. These are listed below: 1. $LMARK Default value is 1. Setting this to -1 before using the SYSTEM control statement will prevent markers from ever being downloaded into the SSP. The minimum SSP system BNLBAS (see section 4) uses $LMARK for this purpose. 2. $RSAV0 Default value is 0. This, together with $RSAVL, controls the subroutine register-save range. $RSAV0 can be 0 to 11, decimal. 3. $RSAVL Default value is 12. This, together with $RSAV0, controls the subroutine register-save range. $RSAVL can be 1 to 12, decimal, and must be greater than or equal to $RSAV0. When the SUBROUTINE statement is used, an instruction is generated that saves all registers between $RSAV0 and $RSAVL, inclusive. These registers are restored by an instruction generated by the RETURN statement. $RSAV0 and $RSAVL should be changed just prior to the SUBROUTINE statement; the SUBROUTINE statement restores the default values of $RSAV0 and $RSAVL when finished. NOTE: If $RSAV0 and $RSAVL are equal, no registers will be saved. 4. $SUBTR Default value is 1. If $SUBTR is non-zero, subroutine call-tracing is enabled. Call tracing causes an extra store instruction to be added just before the branch-and-link of a subroutine call (inside the CALL macro), and another store instruction to be added just after the branch-and-link. These two store instructions keep the current contents of register 13 (which is the current routine's save area pointer as well as the default base register) in system location $TRACE, which is used by the host to trace subroutine calls by tracing the routines' save-areas. Setting $SUBTR to zero suppresses call tracing. Page 17 5. $VMFLG Default value is 0. If $VMFLG is non-zero, markers will be generated for the $VIRTUAL PSECT, which is used by the VIRTUAL statement. This will be necessary if symbolic debugging is done on programs containing arrays defined with the VIRTUAL statement. See section 7.3, Notes on Addressing. 6. $WARN Default value is 1. If $WARN is non-zero, warnings are enabled. Setting $WARN to zero will suppress warning messages. Page 18 Section 3 Invoking the Cross Assembler and Linker The BNL cross assembler macro library, SSP system, and related files are contained in the directory assigned to the logical device BNL$SSP:, which currently is DUA0:[SSP] on BNLMPS::. Before doing anything else, the user should execute the command file BNL$SSP:BNLSSP.COM; this defines the BNL Cross Assembler commands, including CROSS, SLINK and BLINK. (See the "BNL Access Routines for the SSP User's Guide", in file BNL$SSP:SSPAR.MEM, for information on the command file BNL$SSP:BNLSSPINT.COM.) Assembling Source Files The BNL cross assembler is called up with the command: $ CROSS file where "file" is the name of the file to be assembled. If "file" is not specified, you will be prompted for a file name. The default file type of BNL cross assembler source files is MAR. The line: Cross assembling [default directory]file will be displayed on the terminal. The file is macro'd with the BNL cross assembler macro library "BNLLIB", and produces an object file of type OBJ, and a listing file of type LIS. After a period of time, ranging from a few seconds to two or more minutes, depending on the size of the input file and speed of the VAX, the line: BNL Cross Assembler for SSP Version 5.10 will be typed out on the terminal. The command CROSS, which is defined by the command file BNLSSP, actually executes the command file CROSS.COM, in BNL$SSP:. The user may define his own macro library, but will have to edit his own version of CROSS.COM to accomodate this. Linking SSP Object Files To link files produced with the BNL Cross Assembler, there are two choices: $ SLINK file(s) or: $ BLINK file(s) Page 19 where "file(s)" is the name of one or more files to be linked. The SLINK and BLINK commands create an executable image file which by default is named after the first filename in "file(s)"; to overide this, use the standard VMS option /EXECUTE (/E is adequate) on the filename in "file(s)" which you wish to have the executable file named after, or use /E=name to produce an executable file of name "name".SSP (if "name" includes a filetype, it will override the default filetype, ".SSP"). To produce a link map, use the /MAP option (/M is sufficient) in the same fashion as the /EXECUTE option; unlike the /EXECUTE option, there is no default for /MAP (no map is produced unless requested). Any of the usual VMS LINKER options, such as /LIBRARY, may be used. Note that these options must be specified on the filename itself, and may not be used on the SLINK or BLINK command. The command SLINK executes the command file SLINK.COM and links SSP object files with the full BNL error/interrupt handler and "system", BNLSYS, with user-defined code and constants starting at SSP PM location 80 (200 byte-wise) and DM location 200. BNLSYS also contains a simple breakpoint-handler, intended for use with the SSP access routine SSPAR, described in the document "BNL Access Routines for the SSP User's Guide" in file SSPAR.MEM (ref. 1). The system subroutines contained in the file BNLSUB are also linked up, and are user-callable. The system subroutines are linked in last, and are the last things loaded into the SSP. BLINK executes the command file BLINK.COM, and links SSP object files with the base-line BNL "system", BNLBAS, which consists of a HALT instruction in PM 0, and a data word for the HALT instruction in DM 20 ($HALT). The locations DM 2C ($PAUSE), for the PAUSE macro, and DM 30 ($TRACE), for subroutine call tracing are also defined in BNLBAS (as of version 4.00), but note that there is no register dump area reserved for the DMPREG macro (DM 40 through DM 7C, $RDUMP). The system subroutines in BNLSUB are not linked in, and there are no breakpoint capabilities in the baseline system. The baseline system is intended for use mainly in the writing of SSP diagnostics, but one could also use BNLBAS.MAR, the baseline system source file, as a starting point for writing alternate SSP systems. Page 20 Examining the contents of SLINK.COM, shown below, an explanation of its operation is offered. $ LINK SYS$INPUT:/OPT,BNL$SSP:BNLSYS,- 'OBJ_STREAM',- BNL$SSP:BNLSUB/LIB,MARKER CLUSTER=A,%X80000 CLUSTER=B,0 CLUSTER=C,200 CLUSTER=E,%X84000 COLLECT=A,$CODE,PM COLLECT=B,$SYSDATA COLLECT=E,$MARKER,MARKER BNL$SSP: is the logical device described above. OBJECT_STREAM is the filespec(s) given by the user, with the default directory prefixed onto it, from the command: $ SLINK file(s) OBJECT_STREAM includes the /EXECUTE option on the first filename in "file(s)" unless otherwise specified by the user. The image produced is executable only in an SSP, and only if properly downloaded. In fact, the VAX sees the whole thing as nothing more than one or more blocks of non-executable data words, since there are no VAX machine instructions contained in the object files or in the executable image file. An options-file (see the LINK command in the VAX/VMS Command Language User's Guide for more details) is specified to be SYS$INPUT, which is just the VMS way of saying "what follows in this command file is to be interpretted as though it were in an options-file". The BNL system BNLSYS (on logical device BNL$SSP:) is linked with the file(s) in OBJECT_STREAM, and the system subroutines in BNLSUB are also linked, from logical device BNL$SSP:. A cluster is created, having name "A" and base address 80000h, another with name "B" and base address 0, a third with name "C" and base address 200h, and a fourth with name "E" and base address 84000h; there is no cluster "D". See the VAX-11 Linker Reference Manual for more details on clusters. In short, think of cluster "A" as being the SSP's program memory (PM), and clusters "B" and "C" as being the SSP's data memory (DM). Cluster "E" is for markers, and may or may not be loaded into the SSPs DM, depending on several programmer-selected conditions; see MARKER in section 2.1, $LMARK in section 2.4, and subroutines DOWN and SSPFMT in section 2 of SSPAR.MEM, "BNL Access Routines for the SSP User's Guide". The BNL Cross Assembler, in the process of carrying out all the macro calls invoked by the programmer (whether he's aware of it or not), puts all generated code into one of several PSECTs (program sections): Page 21 1. $CODE (or, for back-compatibility, PM), which contains all SSP instructions from all modules (subroutines, main programs and system). 2. $SYSDATA, which contains all BNLSYS DM locations. 3. $MARKER (or, for back-compatibility, MARKER), which contains all MARKER-generated data, and which is optionally loaded or not loaded into the SSP. 4. $DATA, $VIRTUAL (used by the VIRTUAL statement), and any programmer-defined PSECTs, which are SSP DM locations. At link time, PSECTs $CODE and PM are "collected" into cluster "A", PSECT $SYSDATA is collected into cluster "B", PSECTs $MARKER and MARKER are collected into cluster "E", and all remaining PSECTs, including DM, VM and programmer-defined PSECTs, are collected into cluster "C". By setting the base address of cluster "A" higher than the highest possible SSP DM address (ie, 80000h), the down-loading routine has an easy job of correctly loading the SSP's DM and PM separately. The down-loader loads image-file words whose addresses are below 80000h into DM, those with addresses between 80000h and 83FFFh (inclusive) into PM, and anything with an address of 84000h or higher is treated as marker data, which is loaded into DM after everything else, if markers are being downloaded. Collecting the DM PSECTs into different clusters is done to control the order of occurance in DM of the several DM PSECTs, of which $SYSDATA must be first. See section 2.1 for a description of the MARKER control statement. The command file BLINK.COM is similar to SLINK.COM, except that BNLSYS is replaced with BNLBAS, and BNLSUB is eliminated. Note that the above description of these command files pertains to the small portion of the command files at the very end; most of the command file simply forms the map, object, listing and source file names from the user input. The programmer may create a command file which uses the SLINK or BLINK command. It is important to note that the VAX-11 MACRO assembler and the linker both have the property of "directory retention" in their input streams: any filename specified in the input stream is assumed to reside in the same directory as the last filename specified in the input stream, unless a directory is explicitly specified. So, if you create your own command file with, say, an object library's file name specified in the linker's input stream, make sure that it's prefixed with a directory or logical device name. Page 22 Section 4 The BNL System for the SSP - BNLSYS References to addresses below are defined in the file BNLSYS.MAR, and, functionally, bear as close a resemblance to the SLAC equivalents as possible - many can be found in the SLAC documents on the SSP, though the names may not be the same. The system address names begin with the dollar symbol "$", and are also defined, for the convenience of FORTRAN programmers who might need access to these SSP locations from the host computer, in the file SSPSYM_DM.INC. The FORTAN equivalents of these system names have the "$" replaced with a "DM_P_", and are defined as FORTRAN (integer) parameters. The BNL system for the SSP consists of: 1. An error handler, which permits recovery from all errors except the always-fatal unsupported op-code. The error handler, in all non-fatal cases, first decides on the appropriate return or recovery address. The system location $ERR_RET is examined, and if zero, the return address is assumed to be the PM address following the instruction which caused the error. If $ERR_RET is zero then the error PSW (which the hardware stores in DM 0 when the error is encountered) is used to generate the return address. The NPA bit in this PSW is checked, and the PSW is either decremented or not, depending on the NPA bit (see the SLAC documents). After calculating the return address, the error handler decides which error this was, and increments a counter. Each possible type of error has its own unique counter. A total-errors counter is also incremented. After incrementing the counter, the error handler loads the PSW with the return address (except if the error was fatal) and returns program control either to where it left off, or to a user-defined error recovery routine. The user must set $ERR_RET if such a recovery routine is to be used, and should take care to zero $ERR_RET if that recovery routine is no longer desired to be used. The SSPAR command "SHOW ERROR" displays these error counters, listed below: $ECT_TOT DM location 80 - Total errors. $ECT_DZ DM location 84 - Divide-by-zero errors. $ECT_OF DM location 88 - Overflow errors (only if enabled). $ECT_UO DM location 8C - Unsuported opcodes (SSP halts each time). $ECT_BCE DM location 90 - Block-count-exhausted errors. Page 23 $ECT_ARB DM location 94 - Arbitration time-outs. $ECT_ADD DM location 98 - Primary address time-outs. $ECT_IOD DM location 9C - I/O cycle time-outs. $ECT_WRP DM location A0 - DM wrap-around errors. $ECT_UTO DM location A4 - Unknown time-outs. $ECT_BSY DM location A8 - Slave busy (SS=1) errors. $ECT_EOB DM location AC - Slave done (SS=2) errors. $ECT_SSX DM location B0 - SS=3,4,5 (unknown code) errors. $ECT_SSE DM location B4 - Slave data errors (SS=6,7). $ECT_UFB DM location B8 - Unknown FASTBUS errors. This is a FASTBUS I/O error that has neither the time-out bit set in the PSW, nor a non-zero SS code. It is possible that such an error results when the SSP tries to read out an improperly functioning slave, which is not obeying FASTBUS protocol. $ECT_CLR DM location 10C - PSW-clear (unknown) errors. $ECT_IOF DM location 110 - Integer overflow errors. $ECT_FOF DM location 114 - Floating overflow errors. $ECT_FUF DM location 118 - Floating underflow errors. $ECT_FRO DM location 11C - Floating reserved operand errors. $ECT_FDZ DM location 120 - Floating divide-by-zero errors. $ECT_BRK DM location 124 - Entries to the breakpoint handler. Overflows (non-floating) will generate errors only if enabled by setting the overflow mask bit in the PSW (bit 14). Time-out errors will occur only if the "enable-time-outs" bit in CSR0 is written to (bit 26). Unknown time-out errors generally indicate a time-out that occured during an attempted secondary-address or data cycle when no AS/AK lock existed, which in turn usually occurs when the programmer has not specified an error-recovery address ($ERR_RET) before executing a block of FASTBUS I/O instructions. 2. An interrupt handler, which permits FASTBUS masters to read the SSP, even though it may be running, by gracefully shutting down the SSP in such a fashion that it will pick up exactly where it left off as soon as some FASTBUS master writes the 804 (hex) pattern to the SSP's CSR0. A running total of SSP interrupts is kept in system location: $INT_TOT DM location BC The contents of $INT_TOT are displayed when the SSPAR command "SHOW" is issued. Page 24 3. A simple breakpoint handler, which is intended as a debugging tool and requires the use of the host FORTRAN subroutine BREAK, which is used by SSPAR. Up to four breakpoints can be handled, along with a "step" and "branch" breakpoint, set automatically when using the debugger in single step mode. 4. A very simple "start-up" system, which first loads register 13 with the main program's register save area address, then branches to the main program. 5. The Buffered Segment Interconnect routines, described in section 5. The BNL system also contains these global symbols (addresses in hex): -- PM -- $P0 PM location 00 - Global "base" address for PM. -- DM -- $PSW0 DM location 00 - Contains the SSP starting PSW. Initially, the interrupts-enabled bit is set. $MAR DM location 04 - The block-transfer byte-count. $INTPSW DM location 08 - The saved error or interrupt PSW. $ERR_RET DM location 10 - User-specified error-return address. $ERROR DM location 18 - Code showing reason for last error. See Appendix B for a list of possible values of this location. $H_CODE DM location 1C - Code showing reason for last halt. See Appendix B for a list of possible values of this location. $HALT DM location 20 - Datum for the HALT instruction. $0SYS DM location 28 - System zero. $1SYS DM location 2C - System one (same as $PAUSE). $PAUSE DM location 2C - Datum for the PAUSE instruction. $TRACE DM location 30 - Current contents of register 13, from the most recent occurance of a "CALL" macro, used for subroutine call-tracing (see the SSPAR command "SHOW CALLS" in the BNL Access Routines for the SSP User's Guide, found in SSPAR.MEM). $SYSPM DM location 34 - Maximum BNLSYS PM address. $SMASK DM location 38 - SSM enable-interrupts macro DATUM. Page 25 $SSPSIZ DM location 3C - The number of DM words in this SSP. $RDUMP DM location 40 - Register dump area, used by the DMPREG macro. $IPL_TOT DM location C0 - Count of starts from PM 80. $LOC_LH DM location C4 - Address of instruction following last CALL BREAK. $PF0_INI DM location C8 - Initial lowest free PM address. $PFREE0 DM location CC - Lowest free PM address. $F0_INI DM location D0 - Initial lowest free DM location. $FREE0 DM location D4 - Lowest free DM location. $FREEL DM location D8 - Highest free DM location. $RETPSW DM location DC - Return from interrupt/error handler PSW (PC corrected). $BRKID DM location E0 - Breakpoint ID (1-6, if stopped at a breakpoint). $FORLIN DM location E4 - "FORTRAN" line number. $LODAT DM location E8 - Encoded date-of-last-downloading. $LOTIM DM location EC - Encoded time-of-last-downloading. $DM_BSI DM location F0 - BSI DM base address. $PM_BSI DM location F4 - BSI PM system start address. $REG13 DM location F8 - System reg. 13 save word. $REG14 DM location FC - System reg. 14 save word. $REG15 DM location 100 - System reg. 15 save word. $BRK_1 DM location 128 - Word-address of 1st break point. $BRK_2 DM location 12C - Word-address of 2nd break point. $BRK_3 DM location 130 - Word-address of 3rd break point. $BRK_4 DM location 134 - Word-address of 4th break point. $BRK_S DM location 138 - Word-address of step break point. $BRK_B DM location 13C - Word-address of branch break point. $SYS_SAV DM location 140 - System-routines' register save-area. ;DM 1C0: $CRATE_PA DM location 1C0 - This SSP's own PA on the crate. $CABLE_PA DM location 1C4 - This SSP's own PA on the cable. $IOREQ DM location 1C8 - IO request word: 0=none 1=read -1=write. $IOLU DM location 1CC - IO LUN (on host). $IOBA DM location 1D0 - IO buffer address. $IOWC DM location 1D4 - IO buffer (32-bit) word-count. $IOWT DM location 1D8 - IO wait(-1)/nowait(0) mode. $IOFM DM location 1DC - IO format address, if .GT. 0, unformatted if 0, FORTRAN "*" format if .LT.0. $IOFS DM location 1E0 - IO format size (word count). $BSI_SS DM location 1E4 - BSI segment select word: 1=crate, -1=cable $BSI_WC DM location 1E8 - BSI count of successfully transferred words. $MARK0 DM location 1F4 - Marker-words start address, if non-zero. Page 26 $PCMSK DM location 1F8 - PC mask for PSW. $CCOSMSK DM location 1FC - Condition-code/Overflow/System mask. DM 200: User defined DM locations start here. Page 27 Section 5 The Buffered Segment Interconnect The Buffered Segment Interconnect, or BSI, is a set of user-callable and SSP-resident routines which permit user written software to access FASTBUS slaves in other FASTBUS segments, be they cable or crate, through a chain of SSPs in much the same way as if there were real FASTBUS segment interconnects (SIs) joining the segments. At present, there is no user-definable routing table or adjustable timeout capability, but a fairly flexible default routing table has been defined which permits access to any slave on a segment which is separated from the originating master's segment by as many as two intervening segments (for a total of four segments being involved). Furthermore, there exists a set of corresponding FORTRAN routines, callable by host-computer programs, which can make use of the BSI feature of BNLSYS directly. See "BNL Access Routines for the SSP User's Guide", found in SSPAR.MEM for more details on the host-resident portion of the BSI routines. The Default Routing Table The default routing table is very simple; the 32 bits of the primary address word are broken up into four bytes. Only the lowest-order byte is a true geographical FASTBUS address; the other three comprise the segment identifier. With true SIs (in geographical addressing mode, case II, page 4-4, section 4.2 and page 10-5, section 10.4, of the FASTBUS hardware specification, December 1983), the user assigns a unique segment identifier to each route that he intends to use, and downloads the SIs with that information. With the BSI routines, however, the three bytes of the segment identifier are used as (up to) three separate geographical addresses. The originating master (be it host-computer with FASTBUS interface, or an SSP) looks at the segment identifier (upper three bytes of the primary address word) and if it is non-zero, uses the high-order byte of the segment identifier as the geographical address of an SSP through which the transaction will be "routed". The originating master then strips off this highest non-zero byte and passes the new primary address on to the SSP indicated by that byte. That SSP in turn does the same, until there are no non-zero bytes in the three-byte segment identifier. The SSP at the end of the line directly engages the slave. The way the BSI routines are set up in the host permits the programmer to call the same routines for slaves in the segment in which the host has direct access as for slaves in other segments; access over multiple segments is completely transparent. Page 28 Section 6 The BNL System Subroutines for the SSP The BNL system subroutines are contained in the object library BNLSUB.OLB. SUBROUTINE BREAK, called with the CALL macro, as "CALL BREAK". BREAK works much like a FORTRAN PAUSE, inasmuch as SSP program flow is halted upon entering the BREAK subroutine, and is resumed as soon as a FASTBUS master writes 804 (hex) to the SSP's CSR 0. A front panel trigger will not start an SSP halted with a call to BREAK. However, the subroutines CBREAK and DBREAK (see below) perform a "soft" halt of the SSP, and may be restarted from front panel triggers. BREAK leaves the SSP otherwise undisturbed, and is both a useful debugging tool and a convenient method of making the SSP wait for an external event before continuing. BREAK updates $LOC_LH to be the address of the instruction following the CALL BREAK statement. BREAK also sets $H_CODE to be $HC_BRK when called. When the SSP is started back up, BREAK zeroes $LOC_LH and $H_CODE before returning control to the calling routine. Subroutine BREAK is defined in the file SBREAK.MAR. SUBROUTINE BSI, called as "CALL BSI", expects a parameter block to be set up by the calling routine, starting at the address contained in BNLSYS location $FREE0. BSI also serves as a system job, executed by BNLSYS in response to an external FASTBUS master's initiating a BSI request. The parameter block has the form: 1st word - command to BSI. The defined commands are: 1. - Write to data space 2. - Read from data space 3. - Write to CSR space 4. - Read from CSR space 5. - Write RB (issues a 1 microsecond RB) 6. - Broadcast write to data space 7. - Broadcast read from data space. Page 29 8. - Broadcast write to CSR space. 9. - Broadcast read from CSR space. 2nd word - Segment select. This is 1 if the far side is a cable segment, -1 if the far side is a crate segment. 3rd word - Final transfer flag. This is -1 if there is to be one transaction only, and 0 if this transaction is only one in a series of transactions, as would be the case in transfering blocks of data that are too large for availble buffers. 4th word - Not currently in use. 5th word - Not currently in use. 6th word - The return-code of BSI. This is zero if all went well, and an error code if not. See Appendix B for a list of these return-codes. 7th word - The primary address of the slave, including the segment identifier bytes, or what's left of them after being stripped by intervening SSPs. 8th word - The secondary address in the slave. 9th word - The word count. This is the number of words to be read from the slave, or written to the slave. 10th word - The buffer address in this SSP that contains or will contain the data. This simply points to word #13, which is the start of the buffer. 11th word - The previous program's restart address. The previous program is the one that had been running in the SSP, and from which control was grabbed by the BSI software. 12th word - The previous program's halt-code. 13th (and higher) words - The buffer in this SSP. Subroutine BSI is defined in the file BSI.MAR. SUBROUTINE BSIGO, a service routine intended for use by subroutine BSI, BSIGO starts a lower-level BSI on this BSI's crate or cable segment. (Mastership must be enabled before calling BSIGO). The primary address of the lower-level BSI must be in register 1, and an error code is returned in register 0. The error code is zero if all's well, -1 if not. Subroutine BSIGO is defined in BSIGO.MAR. Page 30 SUBROUTINE BSIWT, another service routine intended for use by subroutine BSI, BSIWT waits for a lower-level BSI on this BSI's crate or cable segment. (Mastership must be enabled before calling BSIWT). The address of the word containing the primary address of the lower-level BSI must be in a parameter block pointed to by register 1 (standard subroutine argument passing), and an error code is returned in register 0. The error code is zero if all's well and the BSI error code if not. The lower-level BSI's halt code is checked, and an error results if the halt code is not correct. Subroutine BSIWT is defined in BSIWT.MAR. SUBROUTINE CBREAK, called with the CALL macro, as "CALL CBREAK". CBREAK is essentially identical to BREAK, described above, but it clears the SSP's SR and front panel DONE immediately after restarting. SR must be enabled on the crate or cable segment (or both) by the calling routine for CBREAK to actually clear SR on a segment; the front panel DONE, however, is always cleared. CBREAK uses the PAUSE instruction instead of the HALT instruction, which permits the SSP to be restarted with front panel triggers. SUBROUTINE DBREAK, called with the CALL macro, as "CALL DBREAK". DBREAK is essentially identical to BREAK, described above, but it causes the SSP's SR and front panel DONE to be set just before halting, and clears the SSP's SR and front panel DONE immediately after restarting. SR must be enabled on the crate or cable segment (or both) by the calling routine for DBREAK to actually set and clear SR on a segment; the front panel DONE, however, is always set and cleared. DBREAK also uses the PAUSE instruction instead of the HALT instruction, which permits the SSP to be restarted with front panel triggers. SUBROUTINE DEAD, called by "CALL DEAD", causes the SSP to halt after first setting up DM 0 such that any additional attempts to start the SSP will cause the SSP to execute a HALT instruction straight off, thereby preventing any further disturbance of any of the SSP's contents. DEAD sets the halt code to $HC_DED. DEAD is intended to be used whenever some "unexpected" condition arises, such as an attempt to write outside a specified area of DM, which might cause the SSP to run amok, writing over its own DM when it shouldn't, leaving the SSP in a state such that there is no possibility of ever figuring out what went wrong. DEAD provides a means whereby the SSP can be "frozen" up, or hung, at the first sign of something gone wrong; the programmer then can leisurely examine the SSP's contents. Subroutine DEAD is defined in the file DEAD.MAR. Page 31 SUBROUTINE EXIT, called as "CALL EXIT", simply restores DM 0 to 8080 (hex) and sets the halt code to $HC_NRM, indicating normal completion. This is useful with the SSPAR "SHOW BREAK" command, which will give an English message explaining why the SSP is halted, if possible. Subroutine EXIT is defined in the file SEXIT.MAR. SUBROUTINE SETCSR, called as "CALL SETCSR", with register 1 containing the desired lower 16-bit pattern for CSR0. This sets the SSP's CSR0 by writing to the CSR0 bits that would cause the status bits in CSR0 to be the same as the bit pattern contained in reg. 1. SETCSR is intended to provide a method of saving and restoring CSR0. A routine reads CSR0 with the RCSR0 instruction and saves the result. Later, that routine puts that result into reg. 1 and calls SETCSR, which then restores CSR0 to its former value. Subroutine SETCSR is defined in file SETCSR.MAR. SUBROUTINE SEGMAS, called as "CALL SEGMAS" after first loading register 1 with the segment-select word. SEGMAS enables mastership and RB on the crate segment if register 1 is greater than or equal to zero, and enables mastership and RB on the cable segment if register 1 is less than zero. SEGMAS also enables timeouts. SEGMAS does not assert RB on either segment; it merely enables it on the selected segment. Page 32 Section 6.1 64-Bit Arithmetic Routines There are five 64-bit arithmetic routines contained in BNLSUB.OLB. They were designed originally for use with greater-than-32-bit clocks that might be read by the SSP. These routines (except I$24CQ) all have the same calling convention, which is that one argument is passed directly in the register-pair R2/R3, with the high-order bits in R2 (standard IBM convention), and the other argument is passed as a standard subroutine argument (see the CALL statement description). The result is returned in R2/R3; the subroutine argument remains unchanged. The PSW Condition Code bits are set from the result. The subroutine argument must be a longword pair (ie, a quadword), with the high order bits in the first (low-address) longword of the pair (again, this is the standard IBM convention). All 64-bit representations of integers should follow this convention (high-bits in the low-address), so that the LM and STM instructions can be used to load and store R2/R3 in a single step. The routines are: I$ADDQ - Adds the calling argument to R2/R3 and returns the result in R2/R3. I$DIVQ - Divides R2/R3 by the calling argument and returns the result in R2/R3. The remainder is not available. I$MULQ - Multiplies R2/R3 by the calling argument and returns the result in R2/R3. I$SUBQ - Subtracts the calling argument from R2/R3 and returns the result in R2/R3. I$24CQ - Converts two 24-bit unsigned integers into a single 64-bit signed (but always non-negative) integer, with the upper 16 bits zeros. Called with the low 24 bits in R2 and the high 24 bits in R3 (note that this is the opposite order from standard IBM 64-bit integer representation), it returns with the low 32 bits in R3 and the high 32 bits (the upper 16 of which are zero) in R2 (note that this is the standard IBM representaion). This routine is used to convert any CAMAC-read integer pair, such as from a CAMAC scaler in which one channel counts overflows from the other channel, to a 64-bit integer which can then be worked on with the other 64-bit integer arithmetic routines. Page 33 Example (note that the sign bit is the high-bit of the first word): DM A: .LONG 0,12 ;This is 12. B: .LONG 0,<^X8000000> ;This is 2**31 (not a negative number!) C: .LONG 1,<^XFE00703> ;This is 2**32+FE00703h (not negative!) D: .LONG -1,-1 ;This is -1. E: .LONG 0,-1 ;This is 2**32 - 1, not -1. (!!!) F: .BLKL 2 ;Reserved 2 longwords for a result. G: .BLKL 2 ;Reserved 2 longwords for a result. CAMDAT: .BLKL 2 ;Contains two words read from a CAMAC scaler. H: .BLKL 2 ;Reserved 2 longwords for a result. I: .LONG 0,10 ;This is 10. PM LM 2,3,A ;Load A (two words) into R2/R3 CALL I$ADDQ,B ;Add B to A, result is in R2/R3 CALL I$DIVQ,D ;Divide (A+B) by D (-1), result in R2/R3 STM 2,3,F ;Save result in F. CALL I$SUBQ,E ;Subtract E from -(A+B), result in R2/R3 CALL I$MULQ,A ;Multiply by A, result in R2/R3 STM 2,3,G ;Save final result in G, A*((A+B)/(-1)) LM 2,3,CAMDAT ;Load 2 words from a CAMAC-read buffer. CALL I$24CQ ;Convert R2/R3 into 64-bit integer format. CALL I$DIVQ,I ;Divide by I (which is 10). STM 2,3,H ;Store the result. The divide and multiply subroutines are slow, each taking about 250 microseconds to complete. A test for multiply or divide by one is done upon entry to these two routines, resulting in an enormous savings in time for this one case; this permits these routines to be "shut-off" (as far as time-consumption is concerned) simply by setting the value of the lone calling argument to unity. The add and subtract routines are fast, using little more than the minimum subroutine-calling overhead in time and instructions. Page 34 Section 6.2 Floating Arithmetic Routines There are 16 floating arithmetic (and related) routines contained in BNLSUB.OLB. The DEC VAX single-precision floating representation is used exclusively, since that permits use of the .FLOAT VAX-11 MACRO directive in the cross assembler to produce floating-point numbers in a straightforward manner. Using the DEC VAX floating-point standard provides the additional advantage of being able to read floating-point numbers directly from the SSP and decoding them to ASCII with standard FORTRAN FORMAT statements. The SSP has no floating point unit; all floating operations are done in software and are therefore quite slow (roughly eight times slower than a microVAX II). Floating Represention as used by the BNL SSP Floating Point Routines (See VAX-11 FORTRAN User's Guide, Chapter 8 - FORTRAN Implementation Notes) _31_____________ 16_15_________14___________7_6______________0_ |fraction (F2) ... | sign (S) | exponent (E) | fraction (F1) | |-------------------|----------|--------------|----------------| LSB MSB With a number "x" represented as: x = (+/-) f * 2**k "+/-" is "+" if S (bit 15) is 0, and "-" if not. "f" is always positive, and: 1 .GT. f , 1/2 .LE. f The leading bit of "f" is always omitted (the "hidden" bit). F1(shifted up 16 bits) + F2(shifted down 16 bits) + 2**23 "f" = ------------------------------------------------------------ 2**24 Note that the MSB of "f" is bit 6, from F1. "k" is: E(shifted down 7 bits) Note that bit 14 (in E) is the sign bit of E. For E=0, S=0, "x" is defined to be zero, regardless of F1 and F2. For E=0, S=1, "x" is a reserved (illegal) operand, regardless of F1 and F2. The floating-point routines fall into three groups. The first group corresponds to unary operations, such as absolute value, negation, etc. The second group corresponds to binary operations, such as add, subtract, etc. The third group is an interface group, which simply provides FORTRAN-like accessibility to some of the routines in the other two groups, such as absolute value and square-root. Page 35 Unary Routines The unary routines pass the lone operand directly in register 3, and return the result in register 3. 1. F$ABS - Floating absolute value. Called with a floating-point number in register 3, returns the absolute value of that number in register 3. Defined in file FSABS.MAR. 2. F$FLT - Float an integer. Called with an integer in register 3, returns with a floating-point number in register 3. Defined in file FSFLT.MAR. 3. F$INT - Convert to Integer. Called with a floating-point number in register 3, returns with an integer in register 3. Returns zero, and increments the system floating-overflow error counter, if the number is too large to be represented as a 32-bit integer. Defined in file FSINT.MAR. 4. F$NEG - Floating Negative. Called with a floating-point number in register 3, returns the negative of that number in register 3. Defined in file FSNEG.MAR. 5. F$SQRT - Square Root. Called with a floating-point number in register 3, returns the square-root of that number in register 3. F$SQRT is a very inefficient, though accurate, routine. It was intended as a test for the other floating routines, but as a working square-root routine it is included in the library. Defined in file FSSQRT.MAR. Binary Routines The Binary routines pass the two operands directly in registers 1 and 3, and return the result in register 3. 1. F$ADD - Floating Add. Called with floating-point numbers in register 1 and 3, returns with the sum in register 3. Register 1 is unchanged. The SSP PSW's condition codes are also set. Defined in file FSADD.MAR. 2. F$CMP - Floating Compare. Called with floating-point numbers in register 1 and 3, returns the result in register 3, which is: -1 For c(R3) < c(R1) cc: L (low) 0 For c(R3) = c(R1) cc: E (equal) +1 For c(R3) > c(R1) cc: H (high) Page 36 Where the notation "c(R3)" means the contents of register 3. The SSP PSW's condition codes ("cc") are also set, as above. Register 1 is unchanged. Defined in file FSCMP.MAR. 3. F$DIV - Floating Divide. Called with floating-point numbers in register 1 and 3, returns with the quotient c(R3)/c(R1) in register 3. Register 1 is unchanged. The SSP PSW's condition codes are also set. Defined in file FSDIV.MAR. 4. F$IEXP - Floating exponentiation, with integer exponent. Called with a floating-point number in register 3 and an integer in register 1, returns with the result, c(R3)**c(R1) in register 3. Registers 0 and 1 are destroyed. Defined in file FSIEXP.MAR. 5. F$MUL - Floating Multiply. Called with floating-point numbers in register 1 and 3, returns with the product c(R3)*c(R1) in register 3. Register 1 is unchanged. The SSP PSW's condition codes are also set. Defined in file FSMUL.MAR. 6. F$SUB - Floating subtract. Called with floating-point numbers in register 1 and 3, returns with the difference c(R3) - c(R1) in register 3. Register 1 is unchanged. The SSP PSW's condition codes are also set. Defined in file FSSUB.MAR. 7. I$IEXP - Integer exponentiation, with integer exponent. Called with an integer in register 3 and an integer in register 1, returns with the result, c(R3)**c(R1) in register 3. Registers 0 and 1 are destroyed. Defined in file ISIEXP.MAR. Interface Routines The interface routines correspond to function-subroutines in FORTRAN, taking their input from calling arguments, and returning their results in register 3. 1. ABS - Floating absolute value. Called as "CALL ABS,F", with the result (absolute value of the floating number contained in location F) returned in register 3. Defined in file ABS.MAR. 2. IABS - Integer absolute value. Called as "CALL IABS,I", with the result (absolute value of the integer contained in location I) returned in register 3. Defined in file IABS.MAR. Page 37 3. SQRT - Square Root. Called as "CALL SQRT,F", with the result (square root of the floating-point number contained in location F) returned in register 3. Defined in file SQRT.MAR. Page 38 Section 7 Programming Techniques This chapter consists of several groups of notes and remarks that the SSP programmer will find very useful, and ought to be read thoroughly. The SSP was designed at SLAC to follow the IBM 360/370 machine instruction format; A good text which explains in some detail the IBM machine instructions is a book by George Strubble - "Assembler Language Programming: The IBM System/360", published by Addison-Wesley (1971). Section 7.1 Notes on Operand Specification There are certain characters and sequences of characters that will upset the VAX-11 MACRO assembler, and, therefore the BNL cross assembler for the SSP. Such characters or sequences will generally result in one or more (and possibly quite a lot) of VAX-11 MACRO assembler error messages, which generally have little to do with the actual problem, and should be interpreted as indicating that something wasn't typed right, or that the programmer may have a slight misunderstanding as to the "correct" way to specify an operand. Often, the problem can be fixed by using angle brackets, or by getting rid of a special character that was unintentionally used, in much the same way as a FORTRAN programmer would replace "it's" in a FORMAT literal with an "it''s" after getting nailed with an error message which may not correctly state the real problem: a missing apostrophe. 1. Always surround numbers with angle brackets if those numbers are preceded by radix modifiers (such as ^X for hexadecimal) and used as macro arguments, e.g.: MVI A,^XFF ;will not work. MVI A,<^XFF> ;will work. All the instruction, data, and control statements are macros. 2. Never specify the displacement part of an operand in angle brackets if a base or index register is also specified; VAX-11 MACRO does not "correctly" parse out the various macro arguments in such a case, e.g.: <4+3>(,1) ;will not work. 4+3(,1) ;will work. Page 39 <4>+<3>(,1) ;will work. <4>+3(,1) ;will work. 4+<3>(,1) ;will work. 3. If an instruction statement is used when the current PSECT is not PM, or if an "IBM-like" data statement is used when the current PSECT is not DM, a variety of VAX-11 MACRO error messages will occur, complaining for the most part about expressions not being absolute. Section 7.2 Remarks on FASTBUS I/O Instructions Before a FASTBUS I/O instruction will have the desired effect, certain conditions must exist. In particular, the SSP must have crate or cable segment mastership enabled. Writing to bit 8 of CSR0 will enable crate mastership. Also, if time-out errors are desired, these must be enabled by writing to bit 26 of CSR0. If timeouts are not enabled, a wide variety of common FASTBUS errors will cause the SSP to hang on the offending FASTBUS instruction. One should pay particular attention to CSR0, through which a number of conditions may be set. Note that CSR8 is used to set the SSP's arbitration level, and cannot be set by the SSP itself. For more details, the programmer is referred to Appendix F, which describes CSR0 and CSR8. As a simpler alternative to directly setting bits in CSR0, the BNLSUB library routine SEGMAS, if called with a zero in register 1, enables mastership and RB on the crate (RB is not asserted, simply enabled); calling SEGMAS with a -1 in register 1 enables mastership and RB on the cable. SEGMAS also enables timeouts. There seems to be some trouble with some of the "macro" FASTBUS I/O instructions. No effort has yet been made at BNL to identify which ones work and which don't, so it is advised that these instructions (the ones that don't begin with the letters "FP") either be avoided or tested first, before incorporating them in a program. The pipeline-write instruction "FPWP", mentioned only in the early SLAC documents describing the SSP, does not work at all. Some instructions seem to work well on another SSP as a slave, but may not work on other FASTBUS slave modules. For example, SSPs can only marginally, if at all, access an FDM (Struck 161). The fault here does not appear to lie in the SSP; the slaves in question seem to respond to DS with a DK Page 40 just a tad too quickly, before they're really ready for another DS. The SSP, being a faster FASTBUS master than that with which these slaves were probably debugged, apparently gets another DS into these slaves too soon for the slaves' liking. The circuitry on these slaves' DK lines is not trivial, and it is not simple to delay this DK before it goes out on FASTBUS without installing a new bug in the slaves' hardware. One solution which seems to work well for the FDM, though it is a bit of a cheat, is to delay the slaves' DS, coming in from FASTBUS. Even with a modified FDM, the FPWI instruction does not work, though it works fine on another SSP. It had been previously stated that SSPs do not work well with FBDs, and that FBDs need a modification to work with SSPs. It has since been discovered that some slightly malfunctioning CAMAC type A-1 crate controllers can cause a problem with the FBD that is more severe if the FBD is accessed at a high rate (ie, by an SSP), and was apparently fixed (in some cases) by a modification to the FBD; the modification is not the cure to the real problem. Hence, FBDs do not need modification for this purpose (they do work well with SSPs). However, the FBD does need a modification if it is desired that it produce SS responses to No-Q conditions for F-codes other than 0 through 7. For more details, read the file FBDMOD.TXT. Sometimes an SSP (always acompanying an SSP software bug) may set its RB, but not clear it. If this happens, the SSP will need to be reset with an RB on the opposite segment (i.e. cable or crate) to the one on which it's setting the RB, since the SSP is ignoring RB on the other segment (which it must do, or else everytime the SSP set RB, it would reset itself and stop). If there is no computer access to the other segment, the only way to fix this problem is with the offending SSP's front panel "reset" switch. This sort of thing is most likely to happen if the SSP program loses its base register (which would generally be due to a program bug) and executes a WCSR0 instruction with what is essentially a random bit pattern, setting the RB line. Without a lot of luck, the RB line would then remain on. Note that it is the program's responsibility to clear RB after setting it; RB doesn't ever timeout or clear by itself. The programmer who uses the SSP FASTBUS instructions should specify an error return address to BNLSYS, through the BNLSYS DM location $ERR_RET. If no such error return address is specified, and if the SSP times-out during a primary address cycle, it will return from the error handler to the instruction following the primary-address Page 41 instruction, which will usually be a secondary address or data cycle, which of course will generate an additional (and often misleading) error. Section 7.3 Notes on Addressing Base and Index Registers SSP Memory is addressed by instructions in one of two ways, indexed and non-indexed. In the non-indexed case, the instruction specifies a base register and a 12-bit offset, called the displacement. The contents of the specified base register is added to the displacement field, with the sum being accumulated in an internal addressing register. This sum is then the absolute address of a memory location. In the indexed case, the instruction also specifies an index register, in addition to the base register and 12-bit displacement. The contents of the index register is added to the sum of the 12-bit displacement and the contents of the base register to compute an absolute address. Note that the base and index registers are (in this regard) completely interchangable; it is a matter of definition only that one is called "base" and the other "index" (see, however, the paragraph on Address Computation Pipeline Contention, later in this section). In both cases, the nature of the instruction itself determines whether a DM or PM location is accessed. Furthermore, if zero is used as either the base or index register, rather that use the contents of register zero, the SSP uses the value zero directly. Base registers may be "implied" or "explicit", depending on how the programmer specifies them in the instruction. An intruction's memory reference is written explicitly as "D(X,B)" for displacement, index, base, and "D(B)" for displacement, base. The memory reference may also be written symbolically, as "S" or "S(X)"; in such a case, the cross assembler converts "S" to the appropriate explicit form and determines which register to use as the base, drawing from a set of one or more registers declared to be base registers. The IBM programmer would invoke the "USING" statement for this purpose, but the SSP programmer needn't bother with this. Though the "USING" statement is defined and may be used - see Appendix J - the SSP programmer may take advantage of a number of transparent features of the BNL cross assembler which, among other things, totally obviate the need for the USING statement. Page 42 Normally, base registers are not explicitly specified by the programmer. No base register need be explicitly specified by the programmer if only 4K bytes of data memory are used in a given routine or module; the main program and each subroutine ("routines") are entered with register 13 already set up as the implied base register (reg. 13 is also the pointer to the routine's register-save area), so that each routine is guaranteed access to 4 Kbytes of data memory without the user having to take any action with USING statements. 4 Kbytes of DM is more than adequate for most purposes, execpt when large data areas (such as arrays or buffers) are used by that routine. Usually, large areas are accessed with index registers, base registers not being needed at all. By defining large areas of DM after all other areas have been defined, the probability that a single base register will span everything else becomes respectably large. If the programmer uses VIRTUAL statements instead of DIMENSION or .BLKL or DS statements to define large areas, he can save himself lots of headaches worrying about base registers, and should never have to worry about base resisters at all. Such large areas could also be put in programmer-defined PSECTs; all such PSECTs are assumed to be DM, and are downloaded into the SSP, along with the $VIRTUAL PSECT of the VIRTUAL statement, into high DM, after all other DM has been loaded. In the implicit address case, the programmer specifies a symbol representing a relocatable address, "S", and the assembler figures out which base register to use with that address. The VAX-11 MACRO assembler provides no way for the programmer (and, hence, for the BNL cross assembler) to know if a symbol is absolute or relocatable. Instead, the BNL cross assembler looks at whether a symbol is purely numeric or not (which is done with character string searches), and uses that information to determine if an implied base register is to be used or not. The cross assembler assumes the symbol to be relocatable if it is not purely numeric. The assembler then subtracts the (relocatable) value expected to be in that base register at run time from S and thus computes the displacement D as well as having figured out which register B is. If S is not defined, an error will be generated unless S is followed by "(,)" or "(X,)" (or just "()" with instructions which do not use index registers), in which case the D field will be filled at link time, assuming that S is defined globally in another module (if not, the linker will produce an error message). In this case, D will be S, and no implied base register is used. This will work fine if S can be expressed in 12 bits (if the memory location is in the low 4K). If not, then the address computation will be in error at run time, and there will have been no error message to alert the programmer. In general, if an externally defined address is used, and it is Page 43 not certain that it will be in the low 4K of DM, then the programmer should set up a data word to contain that address, which will be inserted at link time, then load a register with the contents of that data word. That register can then be used as an index register to correctly access the intended external location. See Appendix C for an example of this usage. In the explicit address case, the programmer explicity specifies D (displacement), X (index) and B (base) as absolute expressions or symbols. A locally defined symbol, which is absolute and for which no implied base register should be used, must either be followed with "(,)" or "(X,)", where "X" is an index register, or else preceded with a backslash, "\", which then causes the numeric value of the symbol to be passed as an operand, instead of the symbol itself. Otherwise, a base register will be (incorrectly) assigned. An externally defined symbol which is guarranteed (this is important!) to be in the first 4K (bytes) of DM may also be referenced in this fashion (see Appendix C for an example of external referencing). With external references, there is no way a base register can be used implicitly, since the assembler doesn't know what its value is. If the programmer does not want an implied base register to be used, as is the case if the symbol is absolute, then this must be so specified by following the symbol with an empty or zero base register field, as in "A(,)" for RX instructions or "A()" for other instructions. In the case of purely numerical expressions used as operands, however, this is not necessary; the BNL cross assembler knows when it has been given such a purely numerical expression, and does not use an implied base register with it, so that things like "7" or "44+6" need not be followed with "()" or "(,)". If a macro argument (all the SSP instructions are defined as macros, and the operands are macro arguments) is a locally-defined symbol and is preceded with a backslash "\" (not the "divide", or forward slash "/"), then its numerical value will be passed to the macro, instead of the symbol itself. Therefore, if "A" is a locally-defined absolute symbol, the usage "A(,)" may be replaced by "\A" with the result that an implied base register will not be used. DM References A DM address (or any symbol which the assembler cannot distinguish from a DM address) must, in general, have been defined in the source file prior to its usage as an operand unless it is somehow not subject to implied base register usage. For example, the MVI instruction uses its second operand (the "immediate value" operand) directly, without any kind of base register usage possible, so that this Page 44 "immediate value" operand need not be previously defined, nor need it be defined in the same source file in which it is used as the MVI "immediate value" operand, as long as it is defined as global in exactly one module that will eventually be linked with the module containing the MVI instruction. Note that .ADDR and .LONG produce equivalent results with the BNL cross assembler. PM Addresses For PM addresses, which are only used in the branch instructions (and the LA or LAPM instructions), no implied base register usage exists; the explicit form is always used. There is never any need, nor is there any capability, to use implied base registers for program memory locations. The entire 4K word space of the SSP's PM is spanned by the 12-bit displacement field (since PM words are word-addressed by the SSP, not byte-addressed, like DM). The previous remarks made about implied base registers therefore do not apply to PM address specifications. Base registers may, of course, be used explicitly with PM address references. The BNL cross assembler for the SSP separates DM from PM locations by making use of PSECTs. PM locations are put into PSECT PM, which is defined at link time to have a base address of 80000 (hex). This base address must, of course, be subtracted off from any PM address references before downloading into the SSP. The BNLSYS global symbol $P0 contains this base address, and the LAPM instruction subtracts $P0 from its second operand, so that the PM address is correct after linking. Actually, the LAPM instruction does one more thing to its second operand after $P0 is subtracted off; it divides the address by four. This is necessary because the VAX-11 MACRO assembler does its work by the byte, whereas SSP PM is word-addressed. Both the subtraction of $P0 from the LAPM 2nd operand and the division by four are done by the linker at link time; the LAPM macro sets up an otherwise standard LA instruction, but with the appropriate information for the linker to do this arithmetic. The programmer must keep in mind at all times that PM is word-addressed, especially if any PM address manipulation is done at run time. If a register contains the address of an instruction in PM, and the address of the following instruction is desired, then add one, not four (unlike DM addresses). See the LAPM instruction statement and the .PMADDR data statement. The instruction: LAPM 1,X is identical to the instruction: Page 45 LA 1,0+</4> The "0+" appearing in the LA instruction causes the operand to be identified as numeric and prevents an implied base register from being used. Note that there is no implied base register usage with the LAPM instruction; no special action is needed to prevent a base register from being used, as in the LA case. Address Computation Pipeline Contention To speed processing, the SSP has been designed to be a pipeline-processor, which in this case means that while the SSP is executing an instruction, the address-computation logic simultaneously (in parallel) calculates the address of the next instruction by adding the displacement, base, and index (if the instruction is one that uses an index register). Hence, a problem arises if one instruction modifies a register and the next instruction uses that same register as a base or index. This is called a pipeline contention. The SSP hardware automatically detects such modification of the base register, and delays the address computation in such a case. The index register is not so protected, however, and the programmer needs to exercise care in the use and modification of index registers. The BNL cross assembler does two things to try to alleviate this problem. First, the cross assembler swaps base and index register-fields in an instruction if the programmer makes explicit use of an index register. This reduces the probabilty of a pipeline contention, since base registers are usually modified only when subroutines are called and returned from. Second, whenever code is produced that uses both base and index registers, the listing is flagged with a non-fatal warning. This is to inform the programmer to double-check for a possible pipeline contention, and may be disabled with the $WARN control symbol (see section 2.4). Generally, avoid using both base and index registers unless you are certain that the index register will not be modified within 2 micro-cycles prior to its useage in computing an address. The NOP instruction (no-operation) may be used to produce two dead (wasted) cycles; NOPR produces one dead cycle. Defining multiple subroutines in one file; It is recommended that each program, subroutine and fixed data area be defined in a separate file. Because of the nature of the VAX-11 MACRO assembler, multiple modules defined in a single file will share certain definitions; this is not usually desired, and it can not be controlled. The VAX-11 MACRO assembler does not recognize the SUBROUTINE statement as meaning anything special. A symbol, once Page 46 defined somewhere in a source file, remains defined throughout the assembly of that file, even across subroutine boundries. Therefore, some care must be exercised not to use the same symbol name in two or more routines contained in the same file. This problem vanishes if the routines are contained in separate files and assembled separately. Subroutine argument passing While the CALL statement facilitates argument passing, there is no such facilitation with the SUBROUTINE statement; it is up to the programmer to understand and make proper use of the argument pointer list created by the CALL macro (see Appendix C). Section 7.4 Miscellaneous Notes Reserved Registers The programmer is cautioned about the use of registers 1, 13, 14 and 15, since these are used by the BNL cross assembler for setting up subroutine calls, and by the breakpoint handler in setting up breakpoints. Register 13 also serves as the implied base register when a routine begins execution. Modifying these registers may cause unpredictable results. Register 0 is generally available as a "scratch" register, but its use should be avoided unless the programmer is certain that no "hidden" use is being made of register 0, such as occurs with the INCR and DECR macros. Accessing the PSW condition code bits (CC) The SSP hardware isn't designed to read these bits directly. The breakpoint handler, for example, gets these bits by having the SSP execute an unsupported op-code. The SSP then traps to PM 0 and saves the current PSW, with current CC bits, in DM 0. The error handler stores this PSW in system location $INTPSW (DM 8), identifies the unsupported opcode error as being due to a breakpoint, and jumps into the breakpoint handler. True unsupported opcode errors cause the error handler to halt the SSP. The SSPAR "SHOW" command lists (and labels) DM location $INTPSW, among other things. The SSPAR "SHOW BREAK" command will explicitly list these bits, if stopped at a breakpoint. Page 47 Section 8 Debugging Techinques This section briefly describes the joint use of the SSP access routine, SSPAR (qv ref. 1), and the BNL system for the SSP, BNLSYS, in debugging SSP programs. It is strongly advised that chapter 7, Programming Techniques, be read before attempting to write and debug an SSP program. Before any serious debugging is attempted, ensure that a complete set of assembler listing files for your program and subroutines exist, and also make sure that markers are downloaded into the SSP. The markers are used by the debugging software to find where modules' DM and PM areas start in the SSP, and the assembler listings are used by the debugging software to find specific DM and PM locations symbolically. Things move around when the code is changed and re-assembled, and an out-of-date listing will cause many problems that are unrelated to the bug you're trying to track down. Here are some possible problems which may arise and which may be fixed in a simple way: 1. Can't read or write to the SSP - It may be that the SSP is running. Issue an RB with the SSPAR command "RESET". If that doesn't work, check the front panel lamps; if the "RUN" light remains lit after issuing an RB, briefly set the SSP's front panel "RESET" switch down, then back up. If the "RUN" light remains lit, then either the SSP is malfunctioning or there is some other FASTBUS problem external to the SSP. If the front panel light is not lit, but the problem persists, check that the SSP is installed in the proper slot, and that the SSP's front-panel "RESET" locking-toggle switch is in the "up" position. Issue a "SCAN" command, and see if anything else responds. There is a hardware problem if you can't get past this point. 2. Can't read or write to the SSP after starting it without issuing a "RESET" command - The interrupt enable bit in the SSP's PSW is probably not set (the so-called "system mask", PSW bit 15). The BNL system always starts the SSP with this bit set, so it was cleared by the user-written program (assuming that it was cleared). See section 7, programming techniques, and the INT_ON and INT_OFF instruction statements. It may be that the SSP is stuck in a loop, possibly waiting for something, while it was in an interrupts-disabled state. Page 48 3. The SSP waits "forever" trying unsuccessfully to do I/O with another FASTBUS module. It may be that the SSP's time-outs and bus mastership have not been enabled. See section 6, subroutine SEGMAS, and section 7.2, Remarks on FASTBUS I/O Instructions. Appendix F describes CSR0, and which bits in CSR0 need to be written to to enable these, and other, features. Section 8.1 Debugging Tools To use the debugging tools described here, the programmer needs to use the VAX program SSPAR (in BNL$SSP:), which is described in more detail in the document "BNL Access Routines for the SSP User's Guide", in file SSPAR.MEM. Here, only a brief sketch of the use of SSPAR is offered. 1. Subroutine call tracing - Subroutine call tracing is done with the SSPAR "SHOW CALLS" command, and provides a full trace-back of the current state of subroutine calling in the SSP, unless any subroutines were called with the system control symbol $SUBTR set to zero. Call tracing identifies modules with markers, so markers need to be downloaded. See the SSPAR command "SHOW CALLS" in "BNL Accesss Routines for the SSP User's Guide", found in SSPAR.MEM. 2. Symbolic access to DM and PM locations - The SSPAR commands "EXAMINE" and "DEPOSIT" each take an address-name as their first argument, and "DEPOSIT" takes a value to be deposited as its second argument. Before using these two commands, SSPAR must be told what module is being debugged (use the "MODULE" command), and what listing file to use (use the "LISTING" command). If the listing file is in the current default directory, and has extension ".LIS", and if the module has the same name as the listing file (without the extenstion, of course), then the "DEBUG" command can be used instead of "MODULE" and "LISTING". "MODULE", "LISTING" and "DEBUG" each take a name as their sole argument. 3. Pausing at preprogrammed points - Place a "CALL BREAK" in your code at the desired Page 49 location, then reassemble and relink (this won't work with the BLINK command; BNLSYS and BNLSUB are needed). Then, everytime program control hits the "CALL BREAK", the SSP will dump its registers and halt. The next "GO" command you issue to the SSP (from SSPAR) will cause the SSP to resume execution where it left off. If the register contents are desired at the pause, preceed the CALL BREAK with a DMPREG statement. 4. Breakpoints - This is done with the SSPAR "BREAK" command, which permits online insertion and removal of up to four breakpoints, without having to recompile or relink. The "BREAK" command takes two arguments, the breakpoint number (1 to 4) and the PM (byte) address at which the breakpoint is to be inserted. A breakpoint may be inserted at the beginning of a module with the SSPAR "BREAK/MODULE" command, with the module being specified by name instead of by its PM address. At a breakpoint, the registers are dumped, and program execution halts. Execution resumes upon the next "GO" command. The SSPAR "SHOW BREAK" command will list the status of the six possible breakpoints (showing which are active and inactive, and showing the PM location of the active ones), and will display a one-line English message describing the SSP's current state. If the SSP is halted at a break point (its current state), additional information is described: 1. The breakpoint number which has been hit 2. The PM address of the breakpoint 3. The hexadecimal and reassembled contents of that PM location. 4. A full register dump 5. The SSP's PSW 6. The CC bits (condition code, from the PSW), in a mnemonic-representation: "E" (equal) CC=0, "H" (high) CC=1, "L" (low) CC=2, "O" (overflow) CC=3. The SSPAR "BREAK" command will not place a breakpoint at a branch-and-link instruction, since the instruction at which a breakpoint is placed is moved to a different location. Breakpoints may also not be placed in FASTBUS instructions, since the action of the breakpoint handler causes any existing AS/AK lock to be broken. A message is displayed if an attempt is made to place a breakpoint at an illegal location. Page 50 5. Single stepping - Once the SSP has hit a breakpoint, the SSPAR "SINGLE" command single-steps the SSP, and automatically does a "SHOW BREAK". SSPAR single-steps the SSP by setting the "S" breakpoint to the next instruction. If the current instruction is a branch, the "B" breakpoint is set to the branch destination; whether the branch is taken or not, one of the two breakpoints "S" or "B" will be hit. Once the "SINGLE" command has been issued, pressing "RETURN" repeats the command, until some other SSPAR command is issued. 6. Getting the registers' contents (without breakpoints) - If the register contents are needed but it is not desired to insert a breakpoint in the SSP, the "DMPREG" instruction statement may be inserted in the code at the desired location. To obtain the contents of the registers, as of the last DMPREG statement, use the SSPAR "DREG" command. Of course, this won't work if interrupts aren't enabled. If interrupts are enabled, the SSP will need to be restarted with the "GO" command each time the "DREG" command is used. 7. Freezing the SSP - "permanent" breakpoints In the event of something determined by the user's program to be "fatal" or "nasty", such as the SSP being about to write outside of the area (buffer) where it should be writing (in its own DM), issue a call to the BNLSUB subroutine DEAD. Sometimes, especially if there's a chance that the host may restart the SSP without checking anything first, a simple call to BREAK won't do; for example, the SSP may be about to corrupt a few DM locations, and even if it halts with a call to BREAK, the host may blindly restart it with the result that the SSP goes into a loop and overwrites all its DM. In trying to fix the bug, a programmer would have nothing to go on in such a case. If a call to DEAD is made instead of a call to BREAK, the host may try to restart the SSP until the cows come home, and it won't matter; the SSP will remain stuck, until somebody finally realizes that nothing is happening. The contents of the SSP can then be examined, and the problem isolated and repaired (eventually). The SSPAR command "SHOW BREAK" will state if the SSP is halted due to a call to DEAD, and the command "SHOW CALLS" will show exactly where in the SSP the call to DEAD was made, and will give a complete picture of subroutine nesting at the time the call to DEAD was made. DEAD also dumps the registers. Page 51 8. Getting the condition code bits (CC) out of the SSP - This is best done through the use of breakpoints; see above. (The SSP hardware isn't designed to read these bits directly.) 9. Checking out a proposed source code change - If a bug has been found, and the proposed fix is fairly simple, it may be possible to check it out by using the single-line assembler. This can be done either directly or by editting a command file containing the changes in the form of single-line assembler commands, then executing the command file from SSPAR. If the single-line assembler is used for this purpose, make sure that it's carefully documented; or else you'll find that you've fixed a bug online only to have it come back the next time the program is downloaded. Anything done with the single-line assembler ought to be verified with the de-assembler, which is invoked with the SSPAR "RPM", "RBPM" or "ASSEMBLE" commands. 10. Readable (ASCII) labels for DM locations - This can be done with markers. See the MARKER control statement in section 2.1 and the SSPAR "SHOW MARKERS" command in "BNL Accesss Routines for the SSP User's Guide", found in SSPAR.MEM. Markers can be used to display specific DM and PM addresses, as well as the contents of DM locations, accompanied by some readable ASCII text. Markers can be loaded into the SSP along with the code, and therefore provide a means of easily identifying the program that currently resides in the SSP. While markers were originally used to make it less of a chore to modify specific DM locations used as variable input data, they are a poor substitute for symbolic access to PM and DM locations from SSPAR. 11. Perusing SSP dumps with the simulator - A simulator version of a FASTBUS-to-host interface with an SSP exists which can be downloaded with a file created with the SSPAR "DUMP" command. This permits examining of the SSP's data and program memory contents from a real-time setup (such as a data acquisition system which encountered a fatal error of some kind and issued a call to BNLSYS subroutine DEAD) with all the tools in SSPAR without requiring that a working interface and SSP be available. Simply dump the SSP's memory with the SSPAR "DUMP" command, and proceed, downloading the real SSP with a fresh version of the program and starting again. Meanwhile, the "DUMP" file Page 52 can be downloaded into the simulator SSP DM and PM with the SSPAR "DOWN/VER0" command, and the problem analyzed at leisure without holding up an operation. The simulator does not actually "function" in any way, but for the purposes of reading and writing to memory it is essentially indistinguishable from a real SSP, including SS=2 and SS=6 responses. See the description of the simulator in "BNL Accesss Routines for the SSP User's Guide", found in SSPAR.MEM. Page 53 References 1. BNL Access Routines for the SSP User's Guide, Version 5.10 R. Hackenburg, BNL MPS group Unpublished disk-file manual, (system) logical device and filename: BNL$SSP:SSPAR.MEM. Extant on PHYSNET VAX nodes: BNLMPS, BNLA00, BNL14A (and others) 2. FASTBUS - Modular High Speed Data Acquisition and Control System for High Energy Physics and Other Applications U.S. NIM Committee, December 1983, DOE/ER-0189 3. Assembler Language Programming: The IBM System/360 George Strubble, published by Addison Wesley APPENDIX A CROSS ASSEMBLER ERROR MESSAGES The error messages (and warnings) produced by the BNL cross assembler are shown below. In the event of VAX-11 MACRO error messages, refer to section 2.4. 1. Data memory 512 Kbyte limit exceeded. 2. Program memory 4K limit exceeded. 3. Illegal register number. 4. Illegal displacement. 5. Symbol out of range of base register. 6. PSECT PM may not exist within a FIXED_DATA. 7. Blank argument specified. 8. SYM is not defined. 9. -- Not in use -- 10. PROGRAM statement must be used only once. 11. Error handler too big. 12. Error handler DM area too big. 13. Missing ENDDO statement, or ENDDO out of order. 14. Too many base regs. specified in USING statement. 15. Attempt to DROP a non-base register. 16. -- Not in use -- CROSS ASSEMBLER ERROR MESSAGES Page A-2 17. ENDDO statement out of order. 18. Incorrect DATA syntax. Use: DATA ADDR/VALUE/,etc. 19. Incorrect DIMENSION syntax. 20. Symbol A1 already defined. 21. Incorrect VIRTUAL syntax. 22. PROGRAM or SUBROUTINE statement must appear first. 23. END statement missing or out of place. 24. DATA may not be used on variable already defined. 25. Unknown argument in END statement. In addition to the error messages, several non-fatal warning messages are also defined. Warnings may be disabled by setting the system symbol $WARN to zero, and re-enabled by setting $WARN to one. 3. Index and base registers are same. 4. Possible index register contention. 5. Bad save-reg. range. 6. Replace "COMMON" with "FIXED_DATA" for future releases. APPENDIX B SYSTEM ERROR AND HALT-CODES Error-Codes The error-codes, as defined by the BNLSYS error handler, and found in system (global) location $ERROR are: 1. (SS=1) FASTBUS I/O operation failed due to slave busy (data cycle) or network busy (address cycle). 2. (SS=2) FASTBUS I/O operation failed due to end-of-block (data cycle) or network failure (address cycle). 3. (SS=3) FASTBUS I/O operation failed due to slave-defined reason (data cycle) or network abort (address cycle). 4. (SS=4) FASTBUS I/O operation failed due to unknown cause. 5. (SS=5) FASTBUS I/O operation failed due to unknown cause. 6. (SS=6) FASTBUS I/O operation failed due to data error (data cycle) or unknown cause (address cycle). 7. (SS=7) FASTBUS I/O operation failed due to data error (data cycle) or invalid internal address (address cycle). NOTE The SSP hardware does not distinguish between an SS=6 (data error reject) and an SS=7 (data error accept). SYSTEM ERROR AND HALT-CODES Page B-2 8. Divide by zero. 9. Arithmetic overflow. 10. Unsupported opcode execution. Fatal error Unsupported opcode execution is the only fatal error. The SSP will halt if such an error occurs, a feature of BNLSYS. The SSP itself would continue even in the event of an unsupported opcode; however, such an error indicates that program control has transfered to an arbitrary portion of PM and that a serious program bug exists. Therefore, BNLSYS deliberately halts the SSP on unsupported opcode errors. 11. Word count overflow occured during a FASTBUS I/O block transfer. 12. Time-out during FASTBUS arbitration cycle. 13. Time-out during FASTBUS primary address cycle. 14. Time-out during FASTBUS data cycle. 15. Data memory wrap-around during FASTBUS block transfer. 16. Time out during FASTBUS data cycle w/o AS/AK lock. 17. Unknown FASTBUS I/O error. 18. PSW-clear-on-entry-to-error-handler error. 19. Fixed overflow error (software-implemented). 20. Floating overflow error (software-implemented). 21. Floating underflow error (software-implemented). 22. Floating reserved-operand error (soft-implemented). 23. Floating divide-by-zero error (software-implemented). The remaining error-codes are BSI software error codes: SYSTEM ERROR AND HALT-CODES Page B-3 32. (20 hex, BS_BUF) BSI data buffer too small. There was not enough room in one of the SSPs along the specified route to transfer the data. This is unlikely to happen, since the BSI routines can get by with buffers as small as one word (which may be very slow), and may indicate that the BNLSYS locations DM_P_FREE0 and DM_P_FREEL are corrupted. 33. (21 hex, BS_STO) Software timeout. The BSI routines will not wait forever for a response from the SSP which is the next level BSI, and this is the error code returned after a fixed number of retries has been made. 34. (22 hex, BS_IPA) Invalid primary address specified. This shouldn't happen, at least not while the default routing table is the only routing table possible. 35. (23 hex, BS_NSP) BSI in path is not an SSP. The route between the initiating master and the end-level slave may contain only cable and crate segments and SSPs. This error indicates that an erroneous attempt was made to route through something that was not an SSP. 36. (24 hex, BS_IVC) Invalid BSI command. Indicates that one of the nine valid BSI functions (read data, write data, read CSR, write CSR, issue RB, read data broadcast, write data broadcast, read CSR broadcast, write CSR broadcast) was not requested. 37. (25 hex, BS_BSY) BSI in path is busy. One of the SSPs along the specified route (BSI) did not have its interrupts enabled, nor did it enable interrupts or halt for any period during the fixed SSP hard-timeout interval of 20 usec, and therefore refused to be part of the route. The busy BSI also failed to grant the interrupt for a fixed number of retries, so that total "timeout" interval is actually determined by a retry-on-error count-limit; the "timeout" interval may not necessarily be a fixed period of time, though neither should it vary much. 38. (26 hex, BS_BNR) The BSI software is not resident in an SSP along the route. One of the SSPs along the specified route did not contain the BSI software; all SSPs along the route must contain this software. Any SSP program linked with BNLSYS contains the BSI software. 39. (27 hex, BS_NTA) An invalid NTA was read during a piecemeal transfer. The NTA as read from a slave between pieces of a transfer that is too large to be made in one block transfer should be one of two values, SYSTEM ERROR AND HALT-CODES Page B-4 given the size of the block, depending on whether the slave is byte-addressable or word-addressable. This BSI error code indicates that the NTA as read from the slave was neither of these two values, even after some number of retries. 40. (28 hex, BS_IIO) An invalid interface operation was attempted; the details depend on the type of interface. Halt-Codes Halt-code values of 01000000 or greater (that is, the upper byte of the halt-code word) are reserved for system use, while values less than this are user-defined. Note that the upper byte of a word in the SSP, which is based on IBM systems, has the same address as that word. This is exactly the opposite in DEC (and other) systems, in which the upper byte's address is three plus the word's address. The halt-codes (upper byte, shown mnemonically and in hex), defined by BNLSYS and the system subroutines, are: $HC_INT (FF) Halt due to an interrupt. $HC_UOP (FE) Halt due to an unsupported opcode (fatal) error. $HC_BRK (FD) Halt due to breakpoint (BNLSYS subr. BREAK). $HC_BDN (FC) BSI done and waiting to be restarted. $HC_BRP (FB) Reserved for future use. $HC_NRM (FA) SSP halted after normal completion. $HC_DED (F9) SSP halted for autopsy of contents. $HC_IOR (F8) SSP halted by internal I/O request. $HC_BER (F7) Breakpoint (fatal) error. $HC_CLR (F6) PSW "clear" on error handler entry. $HC_NYS (F5) SSP not yet started. $HC_BWT (F4) BSI waiting for higher-level BSI. BSI Return-Codes BSI Return-codes are returned to the originator or calling routine by the BSI software in the SSPs and/or the host whenever a BSI transaction occurs, and have this format: 0xx - The "xx" is one of the above-listed error-codes, and is simply the error encountered by a BSI (any SSP with BNLSYS software) along the route specified by the primary address specified (see section 6, SUBROUTINE BSI, and section 5). Note that "xx" values from 1 to 7 are simply the SS code of the slave that the end-BSI tried to read or write. SYSTEM ERROR AND HALT-CODES Page B-5 1xx - The "xx" is an error code corresponding to the interface, and indicates a problem with the FASTBUS-to-host interface, not the SSP. This only occurs during communication between the host and the interface, and is not a true SSP/BSI error. See "BNL Access Routines for the SSP User's Guide", found in SSPAR.MEM. 2xx - The "xx" is a system halt-code, and indicates that a BSI (or the Host-FASTBUS interface) encountered another BSI that died for some reason (the reason being given by the halt-code). APPENDIX C CODING SAMPLE From file SAMPLE.MAR: .LIST MEB ;Causes all binary code produced to be listed. ; ; Never, NEVER, use a naked .LIST directive, since ; this will produce a plethora of printer output. ; If the .LIST directive is used to see what's going ; on inside a particular macro expansion, make sure it's ; followed by a .NLIST directive immediately after ; the macro or macros of interest. ; $VMFLG=1 ;Enable PSECT $VIRTUAL markers, for symbolic debugging. PROGRAM SAMPLE ; ; At this point, the current PSECT is PM, and register 13 is ; the (only) implied base register. Register 13 is already ; loaded with the appropriate value. ; ; ; Define some DM words (NUM_0, etc.) to have initial ; values (0,etc.): DATA NUM_0/0/ DATA NUM_1/1/,NUM_4/4/ DATA I/0/ ; Note that the DATA statement does not need to be ; preceded with a DM statement. ; .GLOBAL BIGBUF ;Permit access to BIGBUF by other modules. VIRTUAL BIGBUF(10000) ;Define a large buffer. ; ; Some standard IBM-like instruction statements: ; (Standard notation is used in the comments, such as CODING SAMPLE Page C-2 ; c(address) or c(register) meaning the contents of a location ; or the contents of a register.) SR 0,0 ;Subtract register 0 from itself ST 0,4(,13) ;Store c(R0) in DM address 4+c(R13) L 1,24 ;Load R1 with c(DM address 24) L 2,NUM_4 ;Load R2 with c(DM address NUM_4). LA 3,4 ;Load R3 with the value 4. LA 1,NUM_4 ;Load R1 with the abs. addr. of NUM_4. A 1,NUM_4(3) ;Add c(DM addr. NUM_4+c(R3) ) to R1. ; ; ; $H_CODE is defined externally, and had better be in the low ; 4K of DM (which it is, being a system location): ; ; Move the hex. value FF into DM loc. $H_CODE ; byte addressed (high order byte). MVI $H_CODE(),<^XFF> ;$H_CODE ==> FFxxxxxx ; Move the hex. value AA into DM loc. $H_CODE+3 ; (low-order byte of $H_CODE). MVI $H_CODE+3(),<^XAA> ;$H_CODE ==> FFxxxxAA ; ; Example of DO statement - register 1 runs from the value ; contained in NUM_1 (1) to the value contained in NUM_4 (4), ; in steps of 1: DO 1,NUM_1,NUM_4 ENDDO ; ; Some standard data statements: DM ;Current PSECT is now DM. NUM_7: .LONG 7 ;Define DM loc. NUM_7 to contain 7. .BLKL 10 ;Reserve a block of 10 long-words of DM. J: .LONG 0 ;One word, containing 0. PM ;Back to PSECT PM. ; ; Similar to the previous DO loop, but the DM location I is ; used instead of register 1 as the index, and two DM ; locations are automatically created to contain the ; values 1 and 4: DO I,1,4 ;Indenting is good practice. CALL DIMWIT,I,J ;Call the dummy sample subroutine. ENDDO ;...with two arguments - I and J. ; ; ; Another DO loop example, but instead of the default step ; size of one, the contents of DM location NUM_0 is used ; as the step size. In this instance, NUM_0 contains 0, ; so the step size is 0 and the loop will not terminate: DO I,NUM_1,NUM_4,NUM_0 CALL BREAK ;Wait to be restarted (BREAK is a system sub). ENDDO ; CODING SAMPLE Page C-3 ; ; Examples of using externally defined locations and large ; data arrays or buffers: ; ; GLOBE and BUFPT are defined externally, and must be in ; the low 4K of DM. The references to these are followed ; by paranthesis (,) in order that the cross assembler ; does not attempt to use a base register with them. ; GLOBE and BUFPT are defined in FIXED_DATA ONE, which is ; not in the same file as this; the FIXED_DATA must ; be linked first, after BNLSYS, and before anything else. ; L 7,GLOBE(,) ;Load R7 with (external) GLOBE. L 6,BUFPT(,) ;Reg. R6 now points a BIGBUF L 2,(6) ;Get first word from BIGBUF L 3,12(6) ;Get 4th word from BIGBUF LA 6,32(6) ;Add 32 to R6. L 4,(6) ;Get 9th word from BIGBUF. LA 1,100 ;Put 100 into R1. $WARN=0 ;Suppress warnings. L 5,(6,1) ;Get 34th word from BIGBUF. ; ( 34 = 100/4 + 32/4 +1 ) L 2,4(6,1) ;Get 35th word from BIGBUF. $WARN=1 ;Reenable warnings. ; ; ; Zero the 1st ten words of BIGBUF: SR 0,0 ;Make a zero. L 2,BUFPT(,) ;Point at BIGBUF. DO 3,0,36,4 ;R3 goes from 0 to 36 in 4s. $WARN=0 ;Suppress warnings. ST 0,(2,3) ;Zero a word in BIGBUF. $WARN=1 ;Reenable warnings. ENDDO ; ; The preceeding DO loop could also be done like this: SR 0,0 ;Make a zero. L 2,BUFPT(,) ;Point at BIGBUF. DO I,1,10 ;I goes from 1 to 10 in 1s. ST 0,(2) ;Zero a word in BIGBUF. A 2,NUM_4 ;Increment R2 (the pointer) by 4 bytes. ENDDO ; HALT END From file SAMPLE_FIX.MAR: .LIST MEB ;Causes all binary code produced to be listed. CODING SAMPLE Page C-4 FIXED_DATA ONE ;FIXED_DATAs should come first. ; (They may be in a different file.) ; ; This area contains some DM locations that will be used ; by one or more object modules. ; GLOBE:: .LONG 0 ;Use two colons for global defs. WORLD:: .LONG 1 $G:: .LONG 2 BUFPT:: .LONG BIGBUF ;Set up a pointer to BIGBUF. ; (BIGBUF is defined in another object mod.) ; ; END ;End of FIXED_DATA area "ONE". From file SAMPLE_SUB.MAR: .LIST MEB ;Causes all binary code produced to be listed. ; Sample of how to define a subroutine: ; ; Save registers 0 through 1 whenever the next ; subroutine is called: $RSAV0=0 $RSAVL=1 SUBROUTINE DIMWIT ; ; DIMWIT expects two arguments passed in a pointer list. ; R1 points to that list upon entry into this subroutine. ; DM A: .LONG 0 ;One word, will come from first argument. B: .LONG 17 ;This will be returned as 2nd argument. ; Note: A and B are not actually the subroutine's arguments, ; but "temporary" locations for holding and working on args. PM ; ; How to get an argument: L 2,4(1) ;2nd word in list is pointer to first arg. L 2,(2) ;Get 1st argument (OK to use same register). ST 2,A ;Put it here for the DO loop. ; ; A simple DO loop: DO 1,1,A ;Reg. 1 goes from 1 to A. ENDDO ; ; How to modify and return an argument: L 2,8(1) ;3rd word in list is pointer to second arg. L 0,B ;Put B in R0. ST 0,(2) ;Store R0 in 2nd arg. - arg. now modified. CODING SAMPLE Page C-5 ; RETURN END APPENDIX D ASSEMBLER LISTING SAMPLE A complete set of listings which resulted from the cross assembly of the previously shown coding sample may be found in files SAMPLE.LIS, SAMPLE_FIX.LIS and SAMPLE_SUB.LIS. This appendix will describe SAMPLE.LIS; page numbers in this appendix refer to the SAMPLE.LIS VAX-11 MACRO listing. On page 0 is seen the table of contents, on which is listed the name and version number of the cross assembler as well as the name of the main program. On page 1 some actual code is shown. The four-digit column of hexadecimal numbers which runs down the page, about one-third the way over from the left edge of the paper, gives the current value of the location counter (the DEC ".") on a line. This value is the value before the line is actually assembled, and one must keep in mind that the location counter may be jumping around from PSECT to PSECT (three PSECTs: $CODE, $DATA and $VIRTUAL), depending on the line. At the top of each page, immediately above this column of numbers, is the program name. This name is set by the PROGRAM statement. The SUBROUTINE and FIXED_DATA statements would also set this name, as seen in SAMPLE_SUB.LIS and SAMPLE_FIX.LIS. On some lines, there is an eight-digit hexadecimal number, either to the left of, or instead of, the location counter value. This is a number calculated by the assembler and is either a value which is stored in memory (as either a PM or DM word), a length specifier (such as the number of DM words allocated by a .BLKL statement), or the new value of the location counter, whenever the PSECT is changed. In the case of the .LONG or DATA statement, this eight-digit number is the value actually stored in the SSP's DM when the program is downloaded. For instruction statements, this number is the instruction actually loaded into the SSP's PM. If an apostrophe (') follows this number, it means that the number contains a relocatable or externally defined value, and may not be totally resolved until link time - this number may actually change when the object file is linked. For control statements, a whole series of such numbers may be generated, ASSEMBLER LISTING SAMPLE Page D-2 since several instructions and DM words may be generated. The sequence of numbers running down the page, just to the right of the location counter values, give the actual line-number of each line in the listing as it appeared in the source. Lines without a line number were generated by macro expansions. As long the MEB parameter is used with the .LIST directive, only those lines that produce code, or change the value of the location counter, will be displayed. If the .LIST directive is used by itself, without parameters, then all lines produced by the macro expansions will be listed. There are actually quite alot of lines that result from these macro expansions, and they will normally be of no interest to the programmer, so it is cautioned that the .LIST directive never be used without the MEB parameter unless the programmer is really sure of what he is doing. Note that each DATA statement actually gets expanded into lines that set the PSECT to $DATA, then a .LONG statement is generated, with a statement label, then the PSECT is restored to the previous PSECT, in this case $CODE. Instruction statements always generate .LONG directives, with the opcode shifted all the way to the left (the $OP_xx numbers, where xx is the name of the opcode). Index, base, and other register operands are shifted into position, and displacements and immediate values are inserted into these .LONG directives, generating the actual SSP instruction. Note that although the PROGRAM and SUBROUTINE statements declare register 13 to be the base register in each case (with the USING statement), there is no obvious indication of this, since the USING statement generates no code and is part of the macro expansion of the PROGRAM and SUBROUTINE statements. Likewise, the END statement generates a DROP statement, also not shown since it produces no code. However, if one looks through the listing, one will see base register "D" popping up all over the place, attesting to the fact that it has indeed been declared. On page 2 of the listing is seen an example of a generated warning; the A 1,NUM_4(3) instruction statement is the offender. Since register 13 is the implied base register, and since NUM_4 is defined in this program to be relocatable, the cross assembler decided to use base register 13 (D hex.) with the symbol NUM_4. The programmer told the assembler to use index register 3 as well, with the result that both the index and base register fields of this instruction will be used. Because of the pipeline-contention difficulty (see section 7.3), the assembler swapped these two register fields, so that register 13 will actually be the index register, while register 3 will be the index register. The fact that one is index and the other base is really immaterial to the SSP since both are used in the same fashion; the names merely distinguish the two fields in the PM word, except for the ASSEMBLER LISTING SAMPLE Page D-3 pipeline-contention handling. In general, it is far less likely at any given point that a base register will be modified than an index register, so the index register is put into the "safe" field (the base register field) while the base register is put into the "dangerous" field (the index register field). Note the generated instruction on the next line down: 5A1D3050 - the D3050 part is index=D, base=3, displacement=050. In addition to swapping these register fields, the programmer is flagged with a warning, in case it wasn't realized what was being done, so that the programmer may carefully inspect the code and make sure that the register in the index field (in this case 13) is not modified for two cycles prior to the execution of this instruction. If necessary, two empty cycles may be inserted with the NOP instruction statement. The warning can be turned off through the use of the $WARN control symbol (see section 3). APPENDIX E LINK MAP SAMPLE The file SAMPLE.MAP is complete link map and was obtained with the command: $ SLINK SAMPLE/MAP Essentially all the useful information in this map is contained in the first page. This map contains all global symbol values, as well as the base addresses of DM and PM for each module linked together. In the area labelled "Program Section Synopsis" is found a detailed description of the PM and DM used by each module. Modules are the object files linked together, and take on the name of the first program, subroutine, fixed-data, system or diagnostic defined therein. The base addresses listed in PSECT PM have the "artificial" value 80000 (hex) added on to them, which is discarded by the down-loader. Simply subtract off this quantity from the PM bases given in the map to obtain the actual base address of each module's PM. One must keep in mind, of course, that these PM addresses are given in the map as though they were byte-addressed. They are in fact word-addressed, and the true PM base addresses are given by first subtracting off the 80000 (hex) from the PM bases shown in the map, then dividing by four. However, if the SSP access routine SSPAR (qv ref. 1) is used to debug SSP programs, this division by four is not necessary, since SSPAR generally expects the user to input byte-wise PM addresses, which it internally divides by four. The DM bases shown in the map can be used as they are. Since an assembler warning was generated, the linker issues the message "%LINK-W-WRNERS, compilation warnings" etc.; this has no effect on anything, but simply brings the warning to the programmer's attention, in case it was missed earlier. Warnings can be turned off by using the $WARN cross assembler control symbol. APPENDIX F CSR0, CSR8 AND THE PSW The bit maps of CSR0, CSR8 and the PSW are listed here, basically as they are given in the SLAC documention, for the purpose of easier referencing in this document. CSR0 - Write Cycle Most of the write-bits in CSR0 come in pairs, where writing to one bit of a pair enables or sets an SSP feature, and writing to the other disables or clears the same feature. Those bits that are paired are numbered such that one bit is in the lower half-word (16 bits=half-word), and the other bit is in the same position in the upper half-word). Generally, the lower half word contains bits that, when written to, set (or clear) SSP features to the SSP's default or power-up state. 0 - Does a soft halt of the SSP. That is, the SSP is halted without clearing the RUN bit, so that a front panel start-pulse will restart the SSP. 1 - Enables the SSP to assert RB on the crate segment (disables asserting RB on the cable segment). Complementary bit is 17. 2 - Sets the RUN bit (Enables the SSP to run). Complementary bit is 18. 3 - Asserts RB on either the crate or cable segment (not both). Complementary bit is 19. CSR0, CSR8 AND THE PSW Page F-2 4 - Enables the SSP to assert SR on the crate segment (does not affect assertion of SR on the cable segment). Complementary bit is 20. 5 - Assert SR on either the crate or cable segment, or both, or neither; it depends on which segment or segments SR assertion has been enabled (bits 4 and 20, for the crate, 9 and 25 for the cable). Writing to this bit also sets the DONE front-panel LED and sets the DONE front-panel LEMO output to TTL low (open collector TTL!). Sets the internal SR. Complementary bit is 21. 6 - Sets the SSP to single-cycle mode. Complementary bit is 22. 7 - Enables GK up. Complementary bit is 23. 8 - Enables mastership on the crate segment (disables mastership on the cable segment). Complementary bit is 24. 9 - Enables the SSP to assert SR on the cable segment (does not affect assertion of SR on the crate segment). Complementary bit is 25. 10 - Disables time-outs. Complementary bit is 26. 11 - Start the SSP; writing to this bit is the same as sending a NIM pulse to the START front panel LEMO input, if the RUN bit is set. 12 through 15 - Sets the class for case-2 broadcasts. 16 - Enables writing the class. 17 - Enables the SSP to assert RB on the cable segment (disables asserting RB on the crate segment). Complementary bit is 1. 18 - Clears the RUN bit; writing to this bit halts the SSP. Complementary bit is 2. 19 - Stops the SSP's asserting RB on either the crate or cable segment (bits 1 and 17). Complementary bit is 3. CSR0, CSR8 AND THE PSW Page F-3 20 - Disables asserting SR on the crate segment. This does not affect asserting SR on the cable segment. Complementary bit is 4. 21 - Stops the SSP's asserting SR on either, both or neither of the crate and cable segments; also clears the DONE front panel LED and sets the DONE front panel LEMO to TTL high (TTL open collector!). Clears the internal SR. Complementary bit is 5. 22 - Disables single cycle mode. Complementary bit is 6. 23 - Disables GK up. Complementary bit is 7. 24 - Enables mastership on the cable segment (disables mastership on the crate segment). Complementary bit is 8. 25 - Disables asserting SR on the cable segment. This does not affect asserting SR on the crate segment. Complementary bit is 9. 26 - Enables time-outs (the SSP will wait 20 microseconds before timing out). Complementary bit is 10. 27 through 31 - Not used. CSR0 Read Cycle When CSR0 is read, the upper 16 bits contain the manufacturers ID, which is 0106 (hex) for the SSP. 0 - Not used. 1 - Set if SR is asserted on the crate segment. 2 - The state of the RUN bit. 3 - Set if SR is asserted on the cable segment. 4 - Set if assertion of SR on the crate is enabled. 5 - The state of the internal SR. 6 - Set if single cycle mode is enabled. 7 - Set if GK up is enabled. 8 - Set if crate mastership is enabled. 9 - Set if assertion of SR on the cable is enabled. 10 - Set if time-outs are disabled (clear if time-outs are enabled). 11 - Not used. 12 through 15 - The case-2 broadcast class. CSR8 Write Only. CSR0, CSR8 AND THE PSW Page F-4 Bits 0 through 6 are the arbitration level bits (AL lines). Bit 7 is the assured access bit. PSW Read/Write Bits 0 through 11 comprise the program counter. 12 - Condition Code bit 1 13 - Condition Code bit 2 14 - Overflow mask; overflows will not generate errors unless this bit is set. 15 - System mask; the SSP will not grant interrupts unless this bit is set. The SSM instruction will set and clear this bit by writing a data pattern to the PSW, which is what the INT_ON and INT_OFF macros do. The remaining PSW bits are read-only, and are set when the SSP traps into its error/interrupt handler: 16 - NPA (Next Prom Address) 17 - Exception bit 1 18 - Exception bit 2 19 - Set if the SSP was asserting WT (wait). 20 - Set if the SSP was asserting RD (read-cycle in progress). 21 - The state of the MS00 line. 22 - The state of the MS01 line. 23 - Set if an AS/AK lock was established. 24 - Set if a primary address cycle was in progress. 25 - Set if there was a bus request by the SSP. 26 - The state of the SS00 line. 27 - The state of the SS01 line. 28 - The state of the SS02 line. 29 - Set if the SSP timed-out. 30 - Set if an exception occured (PSW bits 17 and 18: 00-zero divide, 01-arithmetic overflow, 10-Unsupported opcode, 11-FASTBUS block transfer word count overflow). 31 - Set if the SSP granted an interrupt. APPENDIX G THE SLAC INSTRUCTION SET The SLAC instruction set for the SSP, as incorporated into the BNL cross assembler in the form of macro definitions, is show below. The instructions are grouped according to format (i.e. RR, RX, RS or SI). The details of the FASTBUS instructions' operations can be found in the SLAC documentation, and a very good description of the IBM instructions can be found in "Assembler Language Programming: The IBM System/360", by George Strubble (Published by Addison Wesley), Appendix C (ref. 3). IBM-Like Instructions, RR Format: ALR R1,R2 AR R1,R2 BALR R1,R2 BCR M1,R2 M1 is a 4-bit condition mask. BCTR R1,R2 CLR R1,R2 CR R1,R2 DR R1,R2 LCR R1,R2 LNR R1,R2 LPR R1,R2 LR R1,R2 LTR R1,R2 MR R1,R2 NR R1,R2 OR R1,R2 SLR R1,R2 SPM R1 Note that only the R1 field is used. SR R1,R2 XR R1,R2 IBM-Like Instructions, RX Format: THE SLAC INSTRUCTION SET Page G-2 Note: S2 is D(X,B) . A R1,S2 AH R1,S2 AL R1,S2 C R1,S2 CH R1,S2 CL R1,S2 D R1,S2 IC R1,S2 L R1,S2 LA R1,S2 LH R1,S2 M R1,S2 MH R1,S2 N R1,S2 O R1,S2 S R1,S2 SH R1,S2 SL R1,S2 ST R1,S2 STC R1,S2 STH R1,S2 X R1,S2 RX instructions in which the S2 field must be a PM address: BAL R1,S2 BC M1,S2 BCT R1,S2 IBM-Like Instructions, RS Format: Note: S1 is D(B) . LM R1,R3,S1 STM R1,R3,S1 In the following RS instructions the R3 field is skipped: (The R3 field in these instructions must not be specified, or else it will be misconscrued by the cross assembler as being the S1 field, and incorrect code will be produced.) SLA R1,S1 SLDA R1,S1 SLDL R1,S1 SLL R1,S1 SRA R1,S1 SRDA R1,S1 SRDL R1,S1 THE SLAC INSTRUCTION SET Page G-3 SRL R1,S1 In the following RS instructions the S1 field must be a PM address: BXH R1,R3,S1 BXLE R1,R3,S1 IBM-Like Instructions, SI Format: CLI S1,I2 MVI S1,I2 NI S1,I2 OI S1,I2 TM S1,I2 XI S1,I2 In the following SI instructions the I2 field is not used: LPSW S1 SSM S1 Extended Mnemonics, RR Format: Mnemonic: Same as: Branch if: BR R2 BCR 15,R2 Unconditional branch-register NOPR BCR 0,0 No-op, 1 cycle Extended Mnemonics, RX Format: (The cases listed in parenthesis are for branches following a TM "Test under Mask" instruction.) Mnemonic: Same as: Branch if: B S2 BC 15,S2 Unconditional NOP BC 0,0 No-op, 2 cycle BH S2 BC 2,S2 High BL S2 BC 4,S2 Low BE S2 BC 8,S2 Equal BNH S2 BC 13,S2 Not High BNL S2 BC 11,S2 Not Low BNE S2 BC 7,S2 Not Equal BO S2 BC 1,S2 Overflow (or Ones) BP S2 BC 2,S2 Plus BM S2 BC 4,S2 Minus (or Mixed) BZ S2 BC 8,S2 Zero (or Zeros) BNO S2 BC 14,S2 Not Overflow (Not Ones) BNP S2 BC 13,S2 Not Plus THE SLAC INSTRUCTION SET Page G-4 BNM S2 BC 11,S2 Not Minus BNZ S2 BC 7,S2 Not Zero FASTBUS I/O Primitive Instructions, RX Format: In all the FASTBUS I/O instuctions in which a primary address cycle is performed, note that the R1 field is not a register reference, but rather an MS bit mask. The S2 field is an address of a one or more word parameter block, which may contain one or more of the following: Primary address (PA), Secondary address (SA), Word count (WC), Buffer address (BA), or a datum (D). The expected parameter block structure is indicated for each FASTBUS instruction by a series of abbreviations (the ones just shown) which follow the S2 operand in the correct order. FPA R1,S2=(PA) In the following FASTBUS I/O primitive instructions, the R1 field is ignored, but not skipped. The R1 field must always be specified, or else the S2 field will be misinterpreted by the cross assembler as being the R1 field, and incorrect code will be produced. FPR R1,S2=(D) FPRBC R1,S2=(WC,BA) FPRB2 R1,S2=(BA) FPRB2C R1,S2=(WC,BA) FPRNTA R1,S2=(D) FPW R1,S2=(D) FPWBC R1,S2=(WC,BA) FPWI R1,S2=(BA) FPWNTA R1,S2=(SA) FPWP R1,S2=(WC,BA) FASTBUS I/O Macro Instructions, RX Format: (These instructions perform a primary address cycle, and, therefore, the R1 field is not ignored.) FR R1,S2=(PA,SA,D) FRBC R1,S2=(PA,SA,WC,BA) FRB2 R1,S2=(PA,SA,BA) FRB2C R1,S2=(PA,SA,WC,BA) FW R1,S2=(PA,SA,D) FWBC R1,S2=(PA,SA,WC,BA) The remaining macro instructions do not perform a primary address cycle, and the R1 field is ignored: THE SLAC INSTRUCTION SET Page G-5 FSR R1,S2=(SA,D) FSRBC R1,S2=(SA,WC,BA) FSRB2 R1,S2=(SA,BA) FSRB2C R1,S2=(SA,WC,BA) FSW R1,S2=(SA,D) FSWBC R1,S2=(SA,WC,BA) FSWI R1,S2=(SA,BA) SSP-Specific Instructions, RX Format: (In the following three instructions the R1 field is skipped and must not be specifed, or incorrect code will be produced.) RCSR0 S2 WCSR0 S2 WCSR0X S2 In the next instruction the S2 field is ignored: SR32 R1 SSP-Specific Instructions, RS Format: (Byte Shift Instructions - In all of these, the R3 field is skipped and must not be specifed, or incorrect code will be produced.) SLAB R1,S1 SLLB R1,S1 SRAB R1,S1 SRLB R1,S1 APPENDIX H SSP OPCODES SPM 04 ST 50 FR 7A BALR 05 N 54 FRB2 7B BCTR 06 CL 55 FRB2C 7C BCR 07 O 56 FRBC 7D BALR0 09 X 57 FW 7E BCTR0 0A L 58 FWBC 7F BCR0 0B C 59 SSM 80 LPR 10 A 5A LPSW 82 LNR 11 S 5B BXH 86 LTR 12 M 5C BXLE 87 LCR 13 D 5D SRL 88 NR 14 AL 5E SLL 89 CLR 15 SL 5F SRA 8A OR 16 FPA 60 SLA 8B XR 17 FPWNTA 61 SRDL 8C LR 18 FPR 62 SLDL 8D CR 19 FPRNTA 63 SRDA 8E AR 1A FPRB2 64 SLDA 8F SR 1B FPRB2C 65 STM 90 MR 1C FPRBC 66 TM 91 DR 1D FPW 67 MVI 92 ALR 1E FPWI 68 NI 94 SLR 1F FPWBC 69 CLI 95 STH 40 FPWP 6A OI 96 LA 41 WCSR0 6E XI 97 STC 42 RCSR0 6F LM 98 IC 43 FSR 72 WCSR0X 99 BAL 45 FSRB2 73 SLLB 9A BCT 46 FSRB2C 74 SRLB 9B BC 47 FSRBC 75 SLAB 9C LH 48 FSW 76 SRAB 9D CH 49 FSWBC 77 SR32 9E AH 4A FSWI 78 SH 4B MH 4C APPENDIX I BNL INSTRUCTION MACRO SUMMARY The instructions are grouped according to format. RX instructions in which the S2 field must be a PM address: LAPM R1,S2 SI Format: CLIL S1,I2 MVIL S1,I2 NIL S1,I2 OIL S1,I2 TML S1,I2 XIL S1,I2 Macros with no arguments: HALT INT_OFF INT_ON PAUSE Macros with one argument and generating several SSP instructions: DECR S2 INCR S2 APPENDIX J DIFFERENCES BETWEEN THE BNL CROSS ASSEMBLER AND IBM Important distinctions between the BNL Cross Assembler and the IBM assembler are listed below: 1. Instructions (code) and data reside in two separate memories, PM for code and DM for data. This affects all code-addressing, and especially base-register usage. Since the SSP consists of separate program memory and data memory, the programmer needs to excersize some care about which PSECT is currently in effect (see the PM and DM control statements in the section "Control Statements"). 2. The IBM location counter "*" may not be used; instead, the DEC location counter "." is used. This is especially important if the USING statement is employed, which is not necessary with the BNL cross assembler (see section 7, Programming Techniques). 3. Statements are not labelled as in the IBM standard, which is a character string starting in column 1 of the statement to be labelled, but rather as in the DEC standard, which is a character string terminated by one or two colons. 4. IBM radix control (ie, things like =F'509' for full-word-decimal 509) is not in effect. Rather, the DEC radix control is used. This makes for a kind of "mixed standard" assembler language. The programmer familiar with DEC standards and conventions should have no problems with this. 5. No base register need be specified if only 4K bytes of data memory are used; the main program and each subroutine ("routines") are entered with register 13 already set up as the implied base register (reg. 13 is also the pointer to the routine's register-save area), so that each routine is guaranteed access to 4K bytes of DIFFERENCES BETWEEN THE BNL CROSS ASSEMBLER AND IBM Page J-2 data memory without the user having to take any action with USING statements. 6. A pipeline contention problem results whenever an index register is used in computing an operand's address within 2 micro-instruction cycles after that register has been modified. Base registers are protected in hardware from such contention difficulties, but it is the programmer's responsibility to watch for index register contention. 7. Implied base register usage is a bit different in the BNL Cross Assembler, and this is due entirely to the fact that the VAX-11 MACRO assembler provides no method to the programmer of determining whether a symbol is absolute or relocatable, even though the VAX-11 MACRO assembler actually has that information for itself. The IBM Assembler looks at a symbol used as an address, and either uses an implied base register or not, depending on whether that symbol was relocatable or not. The programmer is referred to sections 7.1 and 7.3 for more details. 8. Since the BNL cross assembler was designed for use with the SSP, and in particular since it produces code in separated form (DM separated from PM), no translation process is needed to convert IBM-mainframe-assembled code to SSP-executable code. APPENDIX K MACRO SUMMARY Control Statements CALL name,arg1,arg2,..arg16 (Call subtroutine "name") FIXED__DATA name (Define Fixed Data area DIAGNOSTIC name,start,buffer,nwords,expect,title (Define a diagnostic) DM (Change to Data Memory PSECT) DO index,low,high,step (Define DO-loop) DROP reg1,reg2,...reg16 (Drop base registers) END (End of module) ENDDO or END DO (End of DO-Loop) MARKER symbol,title,indent (Define a Marker) PM (Change to Program memory PSECT) PROGRAM name (Define Main Program) RETURN (Return from subroutine) SUBROUTINE name (Define subroutine) SYSTEM "name" (Define SSP System) USING loc,reg1,reg2,...reg16 (Specify base registers) Data Statements DC val1,...val10 (Define Constant) DCPM val1,...val10 (Define Constant, for PM address) DS nwords (Define Storage) .PMADDR val1,...val10 (PM address data definition) DATA name1/val1/,name2/val2/,.../name10/val10/ (Data definition) DIMENSION name1(len1),...name10(len10) (Array/buffer definition) VIRTUAL name1(len1),...name10(len10) (Array/buffer definition) Instruction Statements, Non-FASTBUS A R1,S2 Add AH R1,S2 Add Halfword AL R1,S2 Add Logical MACRO SUMMARY Page K-2 ALR R1,R2 Add Logical (Register) AR R1,R2 Add (Register) B S2 Unconditional Branch BAL R1,S2 Branch and Link BALR R1,R2 Branch and Link (Register) BC M1,S2 Branch on Condition BCR M1,R2 Branch on Condition (Register) BCT R1,S2 Branch on Count BCTR R1,R2 Branch on Count (Register) BE S2 Branch if Equal BH S2 Branch if High BL S2 Branch if Low BM S2 Branch if Minus (or Mixed) BNE S2 Branch if Not Equal BNH S2 Branch if Not High BNL S2 Branch if Not Low BNM S2 Branch if Not Minus BNO S2 Branch if Not Overflow (Not Ones) BNP S2 Branch if Not Plus BNZ S2 Branch if Not Zero BO S2 Branch if Overflow (or Ones) BP S2 Branch if Plus BR R2 Unconditional Branch-Register BXH R1,R3,S1 Branch on Index High BXLE R1,R3,S1 Branch on Index Low or Equal BZ S2 Branch if Zero (or Zeros) C R1,S2 Compare CH R1,S2 Compare Halfword CL R1,S2 Compare Logical CLI S1,I2 Compare Logical Immediate CLIL S1,I Compare Logical Immediate Long (BNL Macro) CLR R1,R2 Compare Logical (Register) CR R1,R2 Compare (Register) D R1,S2 Divide DECR S Decrement (BNL Macro) DMPREG Dump Registers (BNL Macro) DR R1,R2 Divide (Register) HALT Halt CPU (BNL Macro) IC R1,S2 Insert Character INCR S Increment (BNL Macro) INT_OFF Interrupts Off (BNL Macro) INT_ON Interrupts On (BNL Macro) L R1,S2 Load LA R1,S2 Load Address LAPM R,S2 Load PM Address (BNL Macro) LCR R1,R2 Load Complement (Register) LH R1,S2 Load Halfword LM R1,R3,S1 Load Multiple LNR R1,R2 Load Negative (Register) LPR R1,R2 Load Positive (Register) LPSW S1 Load PSW LR R1,R2 Load (Register) MACRO SUMMARY Page K-3 LTR R1,R2 Load and Test (Register) M R1,S2 Multiply MH R1,S2 Multiply Halfword MR R1,R2 Multiply (Register) MVI S1,I2 Move Immediate MVIL S1,I Move Immediate Long (BNL Macro) N R1,S2 And NI S1,I2 And Immediate NIL S1,I And Immediate Long (BNL Macro) NOP No-op, 2 cycle NOPR No-op, 1 cycle NR R1,R2 And (Register) O R1,S2 Or OI S1,I2 Or Immediate OIL S1,I Or Immediate Long (BNL Macro) OR R1,R2 Or (Register) PAUSE Halt until START-pulse (BNL Macro) S R1,S2 Subtract SH R1,S2 Subtract Halfword SL R1,S2 Subtract Logical SLA R1,S1 Shift Left Arithmetic SLAB R1,S1 Shift Left Arithmetic by Bytes SLDA R1,S1 Shift Left Double Arithmetic SLDL R1,S1 Shift Left Double Logical SLL R1,S1 Shift Left Logical SLLB R1,S1 Shift Left Logical by Bytes SLR R1,R2 Subtract Logical (Register) SPM R1 Set Program Mask SR R1,R2 Subtract (Register) SRA R1,S1 Shift Right Arithmetic SRDA R1,S1 Shift Right Double Arithmetic SRDL R1,S1 Shift Right Double Logical SRL R1,S1 Shift Right Logical SRAB R1,S1 Shift Right Arithmetic by Bytes SRLB R1,S1 Shift Right Logical by Bytes SR32 R1 Shift Right 32 bits (sign extend) SSM S1 Set System Mask ST R1,S2 Store STC R1,S2 Store Character STH R1,S2 Store Halfword STM R1,R3,S1 Store Multiple TM S1,I2 Test under Mask TML S1,I Test under Mask Long (BNL Macro) X R1,S2 Exclusive-or XI S1,I2 Exclusive-or Immediate XIL S1,I Exclusive-or Immediate Long (BNL Macro) XR R1,R2 Exclusive-or (Register) Instruction Statements, FASTBUS (and CSR0) FPA R1,S2=(PA) Primary Address MACRO SUMMARY Page K-4 FPR R1,S2=(D) Single Read FPRBC R1,S2=(WC,BA) Block Read, terminate on Block Count FPRB2 R1,S2=(BA) Block Read, terminate on SS2 FPRB2C R1,S2=(WC,BA) Block Read, terminate on SS2, Block Count limit FPRNTA R1,S2=(D) Read NTA (secondary address) FPW R1,S2=(D) Single Write FPWBC R1,S2=(WC,BA) Block Write, terminate on Block Count FPWI R1,S2=(BA) Single Write Indirect FPWNTA R1,S2=(SA) Write NTA (secondary address) FPWP R1,S2=(WC,BA) Block Write, pipeline (non-functioning) FSR R1,S2=(SA,D) FPWNTA + FPR FSRBC R1,S2=(SA,WC,BA) FPWNTA + FPRBC FSRB2 R1,S2=(SA,BA) FPWNTA + FPRB2 FSRB2C R1,S2=(SA,WC,BA) FPWNTA + FPRB2C FSW R1,S2=(SA,D) FPWNTA + FPW FSWBC R1,S2=(SA,WC,BA) FPWNTA + FPWBC FSWI R1,S2=(SA,BA) FPWNTA + FPWI FR R1,S2=(PA,SA,D) FPA + FPWNTA + FPR FRBC R1,S2=(PA,SA,WC,BA) FPA + FPWNTA + FPRBC FRB2 R1,S2=(PA,SA,BA) FPA + FPWNTA + FPRB2 FRB2C R1,S2=(PA,SA,WC,BA) FPA + FPWNTA + FPRB2C FW R1,S2=(PA,SA,D) FPA + FPWNTA + FPW FWBC R1,S2=(PA,SA,WC,BA) FPA + FPWNTA + FPWBC RCSR0 S2 Read CSR0 WCSR0 S2 Write CSR0 WCSR0X S2 Write CSR0 Commonly used VAX-11 MACRO statements and directives .ADDR a1,a2,...an Specify longword address .ASCII \character-string\ Specify ASCII data .ASCIZ \character-string\ Specify ASCII data, null-terminated .BLKB n Allocate "n" bytes .BLKL n Allocate "n" long words (4-byte words) .BLKW n Allocate "n" words (2-byte words) .BYTE d1,d2,...dn Specify byte data .FLOAT f1,f2,...fn Specify Floating-format data .LONG d1,d2,...dn Specify longword data (4 bytes) .WORD d1,d2,...dn Specify word data (2 bytes)