INTRODUCTION

A BNL787 "system" that provides extra features specific to the BNL787 experiment was developed. The BNL787 "system" for the SSPs is merely an addition to the BNL standard system BNLSYS (see BNL_STANDARD_SYSTEM). It consists of the following parts, which will be further discussed below:

o A "common block" of "fixed" or "defined" locations in DM common to all SSP programs for the BNL787 experiment (BNL787_RES.MAR and BNL787_DEF.MAR)

o A user-dependent "common block" (USER_RES.MAR)

o A main program

o Seven dummy subroutines.

The purpose of the BNL787 "system" is to allow programmers writing code for the BNL787 experiment to standardize on certain parameters and defined symbols at fixed memory locations. It also provides a template that can be used by programmers as a starting point.

It is also clear that a lot of time can be saved by programmers new to the BNL method if example programs are provided, demonstrating some of the techniques that are available. Most of these techniques are now also documented elsewhere (in BNLSSP:|SSP_PROGRAMMER.MEM).

It is hoped that the BNL787 dummy routines and programs provided in the directory 787EXAMPLES: together with this explanation, will perform both these functions.

BUILDING_PROGRAMS

To make use of the BNL787 package, which consists of access to the BNL787 defined locations, use the command

DCROSS filename

to cross assemble the code, and

DLINK filename

to link the program to the BNL787 and USER_RES locations (see later). Note that in order to use the DLINK command, the user must have a file called USER_RES.OBJ (which may be a dummy) in his/her account.

As an example, the file 787EXAMPLES:|DOITALL.COM cross assembles all the files needed for the test program SSP_T, and links them together using the above commands.

SSP-HOST_COMMUNICATION

For the purposes of simplicity in this document, communication will be assumed to be between the programs written in BNL cross-assembly language and downloaded into the SSP (i.e. SSP-resident programs) and those running on a host VAX computer written in FORTRAN (host program). The same principles would apply if the host program was running on the master SSP.

The host program can communicate with the SSP-resident program in two ways: o By accessing the BNL787 defined locations o By accessing user-defined MARKER blocks

Additional Information on:

  • BNL787_defined_locations
  • Marker_blocks
  • SSP_SUBROUTINE_COMMUNICATION

    One of the features of the IBM assembler is that only the lowest 4K bytes of data memory can be accessed without specifically setting up and using a second base register. It is for this reason that the BNL787 fixed locations are located in low memory. Parameters stored in the lowest 4K bytes of DM can be accessed by all subroutines and the main program. (These parameters would be set up as global symbols).

    Consider the simplest case, where a program written using no subroutines accesses less than 4K bytes of data memory. Part of such a program is shown below:

    DM ; Data memory H1: DC 5 ; Location H1 contains 5 Z3: DS 1 ; Reserve space for 1 word PM ; Program memory L 3,H1 ; Load register 3 with contents of ; location H1 ST 3,$TEST ; Store contents of reg. 3 into BNL787 ; fixed location $TEST

    In this case, every data word used can be accessed by the program using only the implied base register (register 13) that has been set up automatically by the BNL cross-assembler. In this case, no base registers are specified.

    Unfortunately, when programs become large, the time required

    to cross assemble the code becomes more significant. For this reason alone, it is desirable to separate large programs into subroutines that can be cross assembled separately and linked together later. Undefined symbols can be resolved at link time.

    When a SUBROUTINE statement is used, the registers are saved according to the contents of the symbols $RSAV0 and $RSAVL, and the base register 13 is reassigned to point to a new value of DM ready for use as the base register of this new subroutine. Thus symbols defined in other subroutines are likely to be out of the range of the implied base register 13, and cannot be accessed easily. However, the first 4K of data memory is still easily accessible to the subroutine (since no base register is needed for this region). But the cross assembler must be specifically told NOT to use the implied base register 13 for these symbols. Consider the following example:

    $RSAV0=0 $RSAVL=10 ; save registers 0-10 SUBROUTINE GO_DO_IT DM ; Data memory H1: DC 5 ; Location H1 contains 5 Z3: DS 1 ; Reserve space for 1 word PM ; Program memory L 3,H1 ; Load register 3 with contents of ; location H1 ST 3,$TEST(,) ; Store contents of register 3 ; into BNL787 fixed location $TEST etc.

    In this case, the subroutine can access the storage location H1 without specifying a base register. (The implied base register 13 is used). However, in order to access the BNL787 fixed location $TEST (a global symbol), the symbol $TEST must be followed by a pair of brackets and a comma, meaning that no base register is to be used.

    Additional Information on:

  • Passing_variables
  • FASTBUS_INSTRUCTIONS

    Additional Information on:

  • MS_code_conventions
  • PROGRAM_EXAMPLES

    Additional Information on:

  • Dummy_routines
  • Working_examples
  • LARGE_ARRAY_ACCESS

    If it is necessary to access data from a part of memory that is outside the range covered by the implied base register, and is not within the first 4K bytes of DM, the following method has been found useful:

    Take the example of a large user data buffer, defined using a VIRTUAL statement. (Note that VIRTUAL,DIMENSION and DATA statements must be located in PM and not DM, otherwise they seem to generate no code and no error message. The IBM-like statements of DC and DS must be in DM.)

    PM ; Program memory VIRTUAL IBUFF(5000) ; data buffer DM ; data memory IBUFF_START: DC IBUFF

    The address of the start of IBUFF will be loaded into IBUFF_START. The VIRTUAL statement will cause the buffer IBUFF to be loaded into DM after everything else. The buffer itself is not reachable from the subroutine without

    setting up a base register. However, IBUFF_START is accessible. An index register can be used to access the buffer IBUFF as follows:

    L 5,IBUFF_START ; load address of IBUFF into register 5 NOP ; prevent index register contention NOP ST 6,0(5) ; store contents of reg. 6 into first ; word of IBUFF LA 5,4(5) ; increment reg. 5 to point to next word ; in buffer (i.e. add 4 bytes) NOP NOP ; prevent index register contention ST 7,0(5) ; store contents of reg. 7 into 2nd ; word of IBUFF

    BASE_REGISTER_SETUP

    If all else fails, it may be necessary to set up a base register to access DM that cannot be accessed otherwise. Consider a SUBROUTINE FRED that sets up a symbol TEST that must be accessed by the SUBROUTINE GROT. An IBM "USING" statement is used to set up register 9 as a base register in FRED. When GROT is called, registers 0-8 are saved, leaving 9 containing the DM address of ISTART in FRED. This can be used as a base register in subroutine GROT to access TEST. The base register may later be dropped with the IBM "DROP" command.

    e.g. SUBROUTINE FRED DM ; Data memory ISTART: DC 1 PM ; Program memory ; Set up a base register for this subroutine USING 9,ISTART LA 9,ISTART DIMENSION TEST(50) ....... CALL GROT .......

    $RSAV0=0 $RSAVL=8

    SUBROUTINE GROT PM ; Program memory USING 9,ISTART L 4,TEST etc.

    INDEX_REGISTER_CONTENTION

    The effects on the programmer of the problem of index register contention have been reduced (if not eliminated) by version 4.00 of the BNL cross assembler, which now swaps base and index registers (if necessary) to avert the problem.

    Prior to Version 4.00, it was necessary to leave (at least) two instructions between modifying a register and using it as an index. Therefore code written for earlier versions often contains NOP (no operation) instructions whose only purpose is to avoid index register contention problems. It was often possible to get rid of the NOPs by ordering the instructions differently, but this made the code hard to read.

    LABELS

    Labels in the code are equivalent to symbols. They can be global (if followed by two colons) or local (one colon). Local symbols must be unique in one file (which may contains several subroutines), but may be reused in different files. Global symbols must be unique throughout.

    A version of SNOOPY has been developed (by A. Daviel, TRIUMF) that will take the global symbols from the map file of the SSP code, and will use these to label DM and PM locations. These are automatically displayed when using the editor in SNOOPY.

    For this reason, it has proved useful to use a few global labels when writing code, as an aid to debugging with SNOOPY.

    Converted from .HLP to .HTML by HLPTOHTML.