ORNL VAX CAMAC System User's Guide By E.T. Blair Published March 15, 1983 CHAPTER 1 INTRODUCTION This document looks at the ORNL/FED VAX CAMAC system from a user's perspective. It attempts to strike the proper balance between concepts, details and techniques so as to make it an educational document, as well as a reference manual for the VAX CAMAC system. The material is organized so that the development flows from concepts to implementation techniques and examples. First, a number of concepts that are essential to the successful use of the CAMAC access software on the VAX are defined and discussed in some detail. Some of these arise out of extensions of standard VAX concepts, while others are more closely tied to the nature of the internal design of the CAMAC system itself. Subsequent chapters deal more directly with the mechanics of using the various CAMAC calls. As one proceeds through this document, it will become obvious that some level of familiarity with the VAX and the FORTRAN language is assumed. This is not to say, however, that one must be a wizard in the internals of the VAX operating system or FORTRAN to be able to follow the discourse. Terms such as "process", "image", "procedure" are used throughout and, while dictionary definitions may suffice for a cursory reading, comprehension of the meaning of such terms in the context of the VAX system is important. All of the examples for using the CAMAC access procedures are written in FORTRAN with a substantial amount of comments to aid the novice FORTRAN programmer in following the flow. CHAPTER 2 VAX CAMAC SYSTEM CONCEPTS The understanding of the concepts described in this chapter is considered a prerequisite for the successful use and application of the VAX CAMAC system. At this point, the discussion divides to concentrate on two categories of topics. One addresses fundamental CAMAC system concepts that are in some sense generic and apply across the entire VAX CAMAC system, while the other deals with a number of powerful CAMAC transaction modes and LAM management seervices available to the VAX CAMAC user. 2.1 Fundamental VAX CAMAC Concepts As stated before in the introduction, some of the VAX CAMAC concepts are direct extensions of standard VAX concepts, while others arise from the design of the VAX CAMAC system itself. This delineation is maintained as specific concepts are discussed throughout this section. 2.1.1 VAX Concepts Extended To The CAMAC System The VAX system offers a wealth of functionality for the development of applications software packages. As a result, many concepts associated with the VAX CAMAC system arise from the utilization of VAX services and/or the application of VAX methodology. Specific topics arising from extensions of standard VAX concepts are listed briefly below. 1. CAMAC Module Names: Logical vs. Physical, 2. CAMAC I/O Synchronization: Wait I/O vs. Proceed I/O, 3. CAMAC Procedures: SUBROUTINE Calls vs. FUNCTION Calls, 4. CAMAC I/O Status Block. VAX CAMAC SYSTEM CONCEPTS Page 2-2 2.1.1.1 CAMAC Module Names: Logical Vs. Physical To motivate this discussion, suppose that the crate number(s) for all of the crates used by a particular CAMAC data acquisition code on the VAX must be changed for some reason. What does the programmer responsible for that piece of code have to change in order to make the program work again? The answer to this question is "NOTHING!". The reason is that when the programmer implemented the data acquisition code on the VAX, logical names were used to identify the CAMAC modules referenced by the code. From considering this hypothetical(and possibly realistic) situation, the power of this concept should be becoming clear by now. The VAX CAMAC system decouples the data acquisition code from the physical location of the CAMAC modules which it needs to reference. At a minimum, one level of deferral is provided in the module addressing scheme. On a large, multi-crate CAMAC system, this logical decoupling can mean rapid recovery from an absolute failure of a CAMAC crate by simply relocating the CAMAC modules, changing the "physical addresses" associated with all of the "logical modules" in the effected crate, and continuing. The programmer responsible for the data acquisition code does not have to make any changes to data files or even worse, the source code. Specifically, "logical module" names must be no more than 32 characters in length, consist of some combination of uppercase alphabetic characters A-Z, and/or any of the special characters. The only restriction on logical module name construction is that it may not begin with an underscore('_') character. This causes special action to be taken by the system service that translates the logical name and will lead to an unsuccessful attempt to perform the desired CAMAC operation. The names should be defined in CHARACTER type variables to insure that the calls to the CAMAC access procedures generate the "right" kind of parameter lists. If one knows his business, other data types may be used. But, since the CHARACTER type is extremely convenient to use for manipulating ASCII text, why bother? A couple of paragraphs back, some mention was made of the "physical address" of a CAMAC module. This deserves some additional discussion. Obviously, some form of information identifying the CAMAC highway driver, crate and station must ultimately be associated with the logical module name that a user code references. The CAMAC system on the VAX is designed so that each crate appears as a VAX device(actually it is more appropriate to think of the "crate devices" as pseudo-devices, since the crates are not directly connected to the VAX UNIBUS). Such a CAMAC crate device is referred to as a Crate Support Unit(CSU). Thus to define the "physical address" for a given CAMAC module, the information required consists of (1) the CSU name and (2) the station number within the crate. In addition to the "physical address" of a given CAMAC module, it is also desireable to have some method for controlling access to the module, i.e. being able to specify some collection of users that can legally perform CAMAC operations to the module. This information, together with the module "physical address", results in a "physical module name". More specifically, the syntax of a physical module name is defined as follows: CSU:[ggg,mmm]Npp where CSU- Specifies the name of the VAX Crate Support Unit(CSU) to be used to reference the CAMAC module. Serial highway CSU names will appear as 'SHxnn', where x specifies the serial VAX CAMAC SYSTEM CONCEPTS Page 2-3 highway driver hardware(i.e. the serial system or branch to which the crate is connected) and nn, interpreted as a decimal number, specifies the crate number. Similarly, parallel highway CSU names will appear as 'PHxn'.Possible crate unit numbers run 1-62 for the CAMAC serial highway, 1-7 for the CAMAC parallel highway. ggg- Specifies the group number(in octal) for VAX users who may legally reference the CAMAC module. The reference control field of the "physical module name" may be omitted, and if so, anyone can reference the CAMAC module. The group number field may also be specified as a wildcard entry '*', indicating that any VAX group may legally reference the module. mmm- Specifies the member number(in octal) for VAX users who may legally reference the CAMAC module. The reference control field of the physical module may be omitted, and if so, anyone can reference the CAMAC module. The member number field may also be specified as a wildcard entry '*', indicating that any VAX member may legally reference the module. Npp- Specifies the CAMAC station number used to reference the CAMAC module. The 'N' prefix is required to satisfy "physical module name" syntax rules. The value specified for the crate number must be consistent with the legal station number range for a CAMAC crate. The number pp is interpreted as a decimal(base 10) value. The association of the "logical module name" to the "physical module name" is accomplished through the use of the VAX logical name system services. These services allow the VAX user to define, translate and delete logical names. Within this framework, access is provided to three levels of "logical name tables". The VAX user may reference the process name table (one's own names), the group name table(names qualified according to group) and the system name table(names having system wide scope). Although special privileges are required to define and delete names from other than one's own process name table, no restrictions are placed on accessing the group or system name tables when translating logical names. The VAX CAMAC system will translate the logical module name that a user specifies in a recursive manner until it finally translates to a physical module name. This final translation must come from the system name table unless the requesting process has 'SYSNAM' privilege, in which case it may come from any table. Since not many users will have such privileged access to the CAMAC system, there obviously must be some way to generate the logical to physical name equivalence pairs in the system name table and some way to control the definition of such names. This is the function of the CAMAC Topology Supervisor, a program(image installed with SYSNAM privilege) that will provide the normal user a means to define logical to physical equivalences and/or modify existing logical to physical VAX CAMAC SYSTEM CONCEPTS Page 2-4 equivalences. For additional information on the CAMAC Topology Supervisor, consult the user's manual for this utility. 2.1.1.2 CAMAC I/O Synchronization: Wait I/O Vs. Proceed I/O While most computer system users never have to worry about the asychronous manner in which modern computer systems actually perform I/O, it is certainly the case that somewhere, hidden from the user, some mechanism is employed to synchronize program execution with the execution of an I/O request by the operating system on behalf of the program. In order to provide the maximum amount of functionality and a minimum of restrictions on situations where the VAX CAMAC access calls could be used, two entry points for each CAMAC I/O procedure are provided. One allows the caller to perform a "proceed I/O" request, the other allows the user to perform a "wait I/O" request. For "proceed I/O", the access procedure returns control to the user's program as soon as the CAMAC I/O request has been queued to the VAX internal software that actually performs the I/O. It then becomes the user's responsibility to discern when that I/O request has actually been satisfied. For "wait I/O", the access procedure returns control to the user's program after the requested I/O operation has been completed. The user does not have to worry about synchronization of the execution of his program with the completion of such I/O requests, because by definition the CAMAC access procedure guarantees that the I/O is complete. With a "wait I/O" CAMAC access call, a program is forced to wait for the requested operation to complete before returning control. Usually, this means the program execution is blocked at that point and someone else gets to use the CPU. There are many instances when the program can continue to perform useful work, even though a CAMAC I/O request may not be complete. This is particularly true in the case where a program is formatting some data to be output to a CAMAC module via large block transfers. Through the use of multiple buffers, the program can be formatting one output buffer while the VAX CAMAC system is actually transmitting another. The VAX operating system provides two very efficient and easily useable methods for synchronizing I/O completion with program execution. They are (1) process local event flag services and (2) Asynchronous System Trap(AST) services. When a CAMAC "proceed I/O" access call is made, the user should specify a local event flag number to be set by the VAX I/O system when the I/O is complete, and optionally, the address of a VAX procedure(FORTRAN SUBROUTINE name) to also be called when the I/O is complete. A longword parameter value(INTEGER*4 constant/variable or an address) may also be specified in conjunction with the AST procedure for this particular I/O request, so that one AST procedure can correctly handle I/O completion for a variety of CAMAC I/O calls if so desired. Specific examples demonstrating the use of both of these techniques may be found in subsequent chapters of this manual. A general discussion of the VAX operating system event flag services and AST services may be found in the VAX/VMS System Services Reference Manual. VAX CAMAC SYSTEM CONCEPTS Page 2-5 2.1.1.3 CAMAC Procedures: SUBROUTINE Calls Vs. FUNCTION Calls On the VAX(as well as many other computer systems), if a subprogram is written as an INTEGER or REAL function, it may be called as either a SUBROUTINE or a FUNCTION. The only thing is that if one calls the procedure as a SUBROUTINE, the value returned via the "FUNCTION name" can not be referenced. All of the VAX system services may be called as either FORTRAN SUBROUTINE subprograms or FORTRAN INTEGER FUNCTION subprograms, in which case a "system status" value is returned indicating successful completion of the requested service or a reason for failure. These "system status" codes are can be translated into corresponding system error/warning/informational messages and displayed if desired. The VAX CAMAC access procedures follow the same convention, returning system status codes as function outputs. A little more discussion of what "success" status from a CAMAC I/O request is necessary at this point. If a CAMAC I/O procedure returns "success" status, it indicates that the I/O request was queued to the VAX internal software that handles the CAMAC I/O. It does not indicate, even for a "wait I/O" request, how the actual I/O operation completed(normally or due to some anomolous condition). In fact, in most cases the CAMAC I/O procedure will always return the "success" indication and the status of real interest will be that actually returned from the VAX internal software that actually performed the CAMAC I/O operation(that's where all of the CAMAC X and Q response information comes from). This "CAMAC status" is returned in a buffer called the "CAMAC I/O status block" and is the subject of the next section in this discourse. At this point one might naturally ask why the CAMAC access software doesn't go ahead and test the "real CAMAC status". The reasons are two fold. First, it would mean that the "wait I/O" access procedure call would diverge considerably in functionality and design from the equivalent "proceed I/O" access procedure(as it stands, there is only one procedure with two entry points). There would still have to be a collection of procedures to analyze the status returned from "proceed I/O" operations. Second, and more importantly, the CAMAC access procedure that performs an I/O operation has no idea of what represents a "normal" response from a given CAMAC module. It is the case that some status indicators signal anomolous conditions that are not connected with the specified CAMAC module addressed by the I/O request and could thus be universally tested on all CAMAC calls by the access software. However, it is also the case that these conditions are the least likely causes for the "failure" of a given CAMAC I/O operation to a given CAMAC module. 2.1.1.4 CAMAC I/O Status Block The I/O status block is a quadword buffer that, as the name implies, receives the completion status of a CAMAC I/O request on the VAX system. The I/O status block associated with a CAMAC I/O request is generated by the CAMAC device driver(VAX internal software that actually performs the CAMAC I/O operation). At I/O completion, the device driver copies pertinent information from the CAMAC highway driver hardware to be returned to the I/O status block associated with the CAMAC I/O request. The capability to return such low level VAX CAMAC SYSTEM CONCEPTS Page 2-6 hardware status for each CAMAC I/O operation is essentially a free good, supplied as part of the VAX I/O system support processing. The interpretation of the CAMAC I/O status block contents hinges on a single bit, also part of the status block. The following pseudo-FORTRAN construct defines the CAMAC I/O status block format for both cases. INTEGER*4 IOSB(2) ! CAMAC I/O STATUS BLOCK ! (QUADWORD BUFFER) INTEGER*2 IOSB_W(4) ! WORD FIELDS OF CAMAC IOSB EQUIVALENCE (IOSB,IOSB_W) PARAMETER (CTR=1) ! CAMAC HIGHWAY DRIVER ! CONTROL REGISTER PARAMETER (BCNT=2) ! BYTES TRANSFERRED/EXECUTE LIST ! BYTES TRANSFERRED PARAMETER (ESR=3) ! CAMAC HIGHWAY DRIVER ! ERROR/STATUS REGISTER PARAMETER (RBCNT=4) ! REPLY LIST BYTES TRANSFERRED ! (VALID FOR LIST MODE ONLY) . . . c++ c c Logic to interpret the CAMAC I/O status block c c-- IF (.NOT.IOSB(1)) THEN IOSB(1) contains system status code, IOSB(2) unpredictable ELSE IOSB_W(CTR) contains final state of CAMAC highway driver control register, IOSB_W(BCNT) contains byte count transferred by the CAMAC I/O operation, IOSB_W(ESR) contains final state of CAMAC highway driver error/status register, IOSB_W(RBCNT) will only be valid(non-zero) when executing a CAMAC command list. If so, it contains the byte count transferred into the reply list. END IF 2.1.2 Design Specific VAX CAMAC Concepts The VAX CAMAC system offers a great amount of flexability to the user. Uppermost in the design is the capability to exercise control over the functionality and performance of the CAMAC system. The user has full control over all default values assumed initially by the CAMAC system. Through the control of the CAMAC module reference method, the user can substantally improve system performance for an application code. VAX CAMAC SYSTEM CONCEPTS Page 2-7 Specific topics arising from the design of the CAMAC system itself are listed briefly below. 1. Basic CAMAC Operations: Single Action vs. Block Transfer, 2. Control Of CAMAC Defaults, 3. CAMAC Module Reference: Direct vs. Keyed, 2.1.2.1 Basic CAMAC OPerations: Single Action Vs. Block Transfer The most elementary CAMAC transfer mode, from a conceptual point of view, is the single action CAMAC request. As is almost always the case with computer systems, the most elementary operations are the least powerful. Single action requests, in keeping with CAMAC jargon are referred to as "programmed I/O" operations. More specifically, the programmed I/O request performs one CAMAC transaction(i.e. a single execution of the specified function code) for each I/O request that the user makes. With a little thought, it should become obvious that this represents a tremendous amount of time spent by the operating system software preparing for and cleaning up after the I/O, with very little time actually required for the CAMAC Highway driver hardware to actually perform the single CAMAC operation. Contrast this with a mode of operation where the CAMAC highway driver can perform several hundred or sereral thousand CAMAC data transfers as the result of a single I/O request from the user. Again, in the jargon of CAMAC, such an multiple action operation is called a block transfer. With such operations on the VAX, the data being written to or read from a given CAMAC module is accessed directly from the VAX memory buffer that you as the user will reference it from(i.e. the CAMAC highway driver hardware performs a DMA transfer of the data). Certain kinds of block transfers may even reference more than one CAMAC module. To simplify understanding one can visualize that these more complex and powerful block transfer/DMA operations are nothing more than implementation, at the hardware level, of sophisticated loops and logic that perform a sequence of single action CAMAC operations on behalf of the user. The most elementary of the block transfer/DMA modes available on the VAX CAMAC system is the Stop On Word Count transfer. With this mode, a specified number of CAMAC data transfers to or from a given CAMAC module are performed, without regard for any status returned from the CAMAC module. Such a transaction terminates when (1) the specified number of data transfers is completed or (2) when an anomolous transmission condition is detected by the CAMAC highway driver hardware. The CAMAC access procedure to perform a programmed I/O on the VAX system is called CAM$PIO or CAM$PIOW for a "proceed I/O" request or "wait I/O" request. The Stop mode request is implemented via the CAM$STOP or CAM$STOPW CAMAC access calls. Together, the programmed I/O CAMAC call and the Stop mode CAMAC call constitute the basic level of functionality required for a CAMAC system. It is probably safe to say that these calls represent the backbone of the VAX CAMAC system VAX CAMAC SYSTEM CONCEPTS Page 2-8 for the average CAMAC user. There are several additional block transfer/DMA modes of operation available to the user. These are identified briefly below with functional descriptions of these more powerful transaction modes deferred to section 2.2. 1. CAMAC Q-Scan Transaction -Performs a CAMAC Q-Scan/Stop On Word Count Operation, 2. CAMAC Q-Stop Transaction -Performs a CAMAC Q-Stop/Stop On Word Count Operation, 3. CAMAC Command List Transaction -Performs a list driven sequence of CAMAC programmed I/O, Q-Scan and Stop mode operations. More information on the detailed calling sequence for all of the VAX CAMAC access procedures may be found in Appendix A of this manual. Examples demonstrating the use of the access procedures may be found in subsequent chapters. In addition, functional descriptions of the block transfer modes listed above may be found under the Advanced CAMAC Concepts section of this chapter. 2.1.2.2 Control Of CAMAC Defaults: The CAMAC Image Block The CAMAC Image Block(CIB) is an area used for data storage by the CAMAC access software. The user does not have to worry about allocating or specifying this area, the linker picks up the necessary data area(program section) when the application program is linked aganist the CAMAC access library(to produce an executable image). The CIB is(or can be) referenced by any of the CAMAC access procedures. Each program(process executing the image) gets it's own private copy of the CIB, even though the executable code of the access procedures themselves is sharable among all programs utilizing the CAMAC system. Thus, the CIB makes it possible for each program(process executing the image) to have and control it's own environment relative to the VAX CAMAC system, independent of what anyone else utilizing the VAX CAMAC system does. Specifically, the CIB contains the following information about the program. 1. Default CAMAC state variables used to influence the manner in which the CAMAC highway driver determines 'ERROR/NORMAL' termination of certain CAMAC operations(specifically, PIO and List PIO). These values are controllable by the program. 2. Default CAMAC state variable to determine the desired memory format to be used on CAMAC I/O requests where the desired memory format is not specified in the CAMAC procedure call as a parameter. This value is controllable by the program. VAX CAMAC SYSTEM CONCEPTS Page 2-9 3. Default process local event flag to be used for both "proceed I/O" and "wait I/O" requests where the event flag number is not specified in the CAMAC procedure call as a parameter. This value is controllable by the program. 4. Default CAMAC I/O status block to be used to receive the status from CAMAC I/O requests where the IOSB is not specified in the CAMAC procedure call as a parameter. 5. Process information, obtained via the GETJPI system service, required by the CAMAC access software. This information is obtained on the initial CAMAC procedure call or on each call to change a CIB default value. 6. VMS I/O channel table maintained by the CAMAC access software to minimize the number of VMS I/O channels assigned by the CAMAC system. The controllable values in the CIB may be modified by the program at any time, although some care should be exercised if the CIB values are modified out of an AST service procedure and the normal program flow utilizes the CAMAC access procedures. The CAMAC access procedure that allows these values to be modified is called CAM$CSTATE and is described in Appendix A of this document. Examples of it's use are also inculded in subsequent chapters. 2.1.2.3 CAMAC Module Reference: Direct Vs. Keyed The VAX CAMAC user has two methods at his disposal to reference a CAMAC module in a call to a CAMAC access procedure requiring CAMAC module identification as an input parameter. These methods are (1) direct module reference and (2) keyed module reference. The methods are defined and contrasted in the following paragraphs. By "direct module reference", it is meant that the "logical module name" is passed to the CAMAC access procedure as a means of identifying the CAMAC module to be referenced by the particluar call. The access procedure must then proceed to translate the "logical module name" recursively until the translation results in a "physical module name" from which the module "physical address" can be obtained. This information is parsed from the "physical module name" and passed to the internal VAX software that actually performs the CAMAC I/O request. By "keyed module reference", it is meant that an encoded "key" value identifying the CAMAC module to be referenced is passed to the CAMAC access procedure. Through the use of a special CAMAC access procedure called CAM$ASSIGN, a "key" value may be equivalenced to a particular CAMAC "logical module name" and then subsequent references to the module made using the specially encoded "key" value as opposed to the "logical name". Since the "key" and the "logical module name" are equivalent, no generality is really lost. The application code still utilizes logical rather than physical addressing and is still insulated from changes of the physical locations of specific CAMAC VAX CAMAC SYSTEM CONCEPTS Page 2-10 modules which it must reference. The advantage of "key" assignment is that the overhead of the logical to physical translation process described in the preceeding paragraph is not incurred on each CAMAC I/O request. Thus, a more efficient CAMAC application code results, achieving more CAMAC I/O requests per unit time than with "direct module reference". A module "key" may also be released by using the special CAMAC access procedure CAM$DASSGN. Specific documentation on these procedures may be found in Appendix A. Examples of their use may be found in subsequent chapters. As one last note to this discussion, it might appear that one would be foolish to perform CAMAC calls with "direct module reference" as opposed to "keyed module reference". In most instances, that is indeed the case. However, the obvious needs to be explicitly stated. By using "direct module reference", one assures himself that the current "physical address" of a given CAMAC module will always be used. With "keyed module reference", this might not always be the case. If for some reason the "physical address" of a given CAMAC module is changed after a program assigns a "key" value to that module, the program receives no positive indication of this fact. CAMAC I/O operations will probably result in "failure" and this should be sensed by the program, with appropriate action taken to define and correct the problem. While this is indeed a hypothetical problem, it remains to be seen if it becomes an operational problem. If so, solutions are available that can cure the problem and do so in a manner that should not involve any application code changes. 2.2 Advanced VAX CAMAC Concepts The discussion in this section primarily centers around some very powerful CAMAC transaction modes. Some of these CAMAC transaction modes are defined in the "CAMAC standard", while, others are extensions that are unique to the VAX CAMAC system. More specifically, these extensions are a function of the chosen CAMAC highway driver hadrware and/or the CAMAC software implementation that supports this hardware. 2.2.1 CAMAC Q-Scan Mode: An Introduction. The CAMAC Q-Scan transaction represents a very powerful method for transferring data to or from CAMAC modules that basically have one "data point" per CAMAC subaddress. The "scan" operation may span accross several CAMAC modules occupying contiguous station addresses within the CAMAC crate. The CAMAC highway driver hardware, once setup, controls the Q-Scan transaction by using the Q response from the previous CAMAC cycle to determine the subaddress and station to be referenced on the cycle about to be performed. Specifically, a Q response of 0 causes the subaddress to be reset to 0, the station number to be incremented by 1 and the CAMAC function code to be repeated. A Q response of 1 causes the CAMAC subaddress to be incremented by 1. If the result exceeds 15, the subaddress is reset to 0 and the station number is incremented by 1. As with Q=0, the CAMAC function code is repeated. The Q-Scan transaction terminates when (1) a specified number of CAMAC transfers have been made or (2) when the station number increments out of legal range or (3) when an VAX CAMAC SYSTEM CONCEPTS Page 2-11 anomolous transmission condition is detected. Obviously, termination due to condition (1) is the desireable one, indicating that the operation was a success. As mentioned before, this particular CAMAC transaction represents a very effieient method for performing DMA/block transfers of data to or from CAMAC modules with one register("memory location") per subaddress. Modules typically falling into this category are multi-channel counters, multi-channel pulse generators, multi-chanel DAC/ADC modules, etc. The applications programmer should be mindful of the Q-Scan capability and utilize it where the CAMAC modules involved allow. The Q-Scan CAMAC access procedure is called CAM$QSCAN(W). A full description of the calling sequence for it may be found in Appendix A. Examples of it's use may be found in subsequent chapters. 2.2.2 CAMAC Q-Stop Mode: An Introduction. The CAMAC Q-Stop transaction represents a very powerful method for transferring data to/from certain types of CAMAC modules where the exact length of the transfer may not(or can not) be known before the CAMAC I/O request is made. This is a DMA/block transfer transaction on the VAX CAMAC system. The Q-Stop operation only addresses a single CAMAC module throughout the course of the transaction. The CAMAC highway driver, once set up, controls the Q-Stop transaction by utilizing the Q response from the previous CAMAC cycle to determine when to terminate the transaction. More specifically, the specified CAMAC subaddress and function codes are repeated successively to a given CAMAC module until (1) a Q response of 0 is received or (2) a specified number of CAMAC transfers are completed or (3) an anomolous condition is detected during the Q-Stop transaction. As mentioned earlier, the Q-Stop transaction offers a very efficient method for transferring data to or from a CAMAC module where the exact length of the transfer may not be known before the the I/O request is made. Types of CAMAC modules that typically fall into this category are communication modules with local memory, FIFO modules, dual port memory modules, etc. The application programmer should be mindful of instances where Q-Stop transactions can(or must) be utilized. The CAMAC access procedure for performing a Q-Stop transaction is called CAM$QSTOP(W). Detailed information on the calling sequence may be found in Appendix A of this manual. Examples demonstrating the use of CAM$QSTOP may be found in subsequent chapters. VAX CAMAC SYSTEM CONCEPTS Page 2-12 2.2.3 CAMAC LAM Management: An Introduction. The term "LAM" appears quite frequently in the jargon of CAMAC. Actually, "LAM" stands for "Look At Me". In a CAMAC crate, each station has it's own LAM line. This LAM signal line may be asserted by a CAMAC module for a variety of conditions, depending on the specifications for the module design. Usually, as one might expect, the LAM signal is utilized primarily to indicate some sort of asychronous event detected by the module or as an indication that the module actually completed some operation which it was enabled to perform. For example, a clock module may be loaded with a specified number of counts and triggered by an external signal. Once triggered, the clock module will count to zero, at which time it might be expected to signal this by asserting the it's LAM signal as an indication of this fact. The fact that CAMAC modules typically assert their LAM signal lines to indicate all sorts of significant conditions is of little use unless the computer system connected to the CAMAC crate has some method of "recognizing" this fact and in turn, notifying an application program that a module associated with it is requesting attention via the LAM signal. This then is the function of LAM management. Namely, to be able to allow CAMAC application programs to be "signaled" when a given CAMAC module has asserted it's LAM signal line. As stated in the previous paragraph, the LAM signaling problem has two parts, (1) the recognition that a module has asserted it's LAM signal line and (2) notification to the applications program that the LAM associated with the module has been recognized. The solution of the first part of this problem is rather complicated, involving a significant amount of hardware and software interaction within the VAX software that actually manages the CAMAC highway driver. The solution of the second part of this problem involves the use of the VAX Asynchronous System Trap services to enable an application program to receive an AST when a LAM from a given CAMAC module is recognized. When the LAM AST is delivered, normal program execution is "interrupted" and a user specified procedure(i.e. SUBROUTINE or FUNCTION) is called. When it returns, the AST is effectively "dismissed" and normal program execution resumes at the point where it was interrupted. With this overview of how a LAM is recognized and the applications program subsequently notified, it is time to take a look at the specific LAM service calls available in the CAMAC access software. There are two approaches that can be taken by the user, (1) a user written AST procedure may be associated with the LAM and called when the LAM is recognized by the CAMAC system, thus allowing the user program to continue normal execution or (2) program execution may be suspended to wait for the occurrence of a LAM from a particular CAMAC module. More specifically, the LAM service access procedures are briefly described below. 1. CAM$LAMAST(W) -Requests a LAM AST when the LAM from a given CAMAC module is VAX CAMAC SYSTEM CONCEPTS Page 2-13 recognized by the CAMAC system. The user specifies his own AST procedure to be called by the system. 2. CAM$CANLAM(W) -Cancels a previously requested LAM AST for a given CAMAC module. 3. CAM$LAMWAIT -Forces the calling program(process) to hibernate until the LAM from a given CAMAC module is recognized by the CAMAC system. A maximum time to wait must be specified with this call. This call uses an internal AST procedure to receive the LAM AST which in turn awakens the hibernating program(process) Detailed information on the calling sequences for these LAM service procedures may be found in Appendix A of this manual. Examples demonstrating the use of these procedures may be found in a later chapter. 2.2.4 CAMAC List Mode: An Introduction This section deals with those concepts associated with CAMAC command list operations on the VAX system. This list capability represents an extremely powerful method for performing sequences of CAMAC operations to one specific CAMAC module, or performing a single CAMAC operation for many different CAMAC modules, or any combination of these scenarios. It should be realized up front, however, that the CAMAC command list capability on the VAX is not simply an extension of the functionality offered by the fundamental CAMAC access calls whereby the software simply links together a number of "command packets" which it executes as a single "CAMAC request". Rather, this command list capability represents separate and distinct functionality, both at the software level and also at the hardware level. Keep this fact in mind as you read the remainder of this section. It is important. To be a little more specific, the CAMAC highway driver hardware on the VAX actually executes the command list. The hardware design dictates the kinds of operations that may be performed from a command list. It also dictates the way in which memory buffers are utilized and ultimately the manner in which an applications program must reference CAMAC data associated with the CAMAC command list or resulting from it's execution. On the software side, the command list procedures provide convenient access to the hardware functionality. They attempt to isolate the CAMAC applications programmer from the details of how associated memory buffers must be formatted and organized to satisfy the hardware. There are, however, some aspects of associated with CAMAC command lists on the VAX that can not be hidden from the user. These will become obvious as one reads through the remainder of this discussion. VAX CAMAC SYSTEM CONCEPTS Page 2-14 2.2.4.1 List Mode Overview There are a few simple concepts associated with list mode operations on the VAX CAMAC system. If these are clearly understood, there should be little chance for confusion about what is actually going on with such operations. Central to list operations is the "command frame" concept. This is nothing more than a block of memory containing the information necessary to perform a desired CAMAC operation and formatted in such a way that the CAMAC highway driver can interpret it correctly. Closely related is the concept of a "data frame" which, again, is nothing more that a block of memory containing the data to be written a given CAMAC module or data read from a given CAMAC module(resulting from the execution of some "command frame") and formatted in such a way that the highway driver can fetch it correctly. With these definitions, one can now define the two list buffers that the VAX CAMAC system utilizes to perform CAMAC list driver operations, namely (1) the "execute list" buffer and (2) the "reply list" buffer. The "execute list" is the CAMAC command list and consists of a collection of command frames and possibly data frames for the command frames that perform CAMAC write operations. The hardware requires that the data frame for a command frame that performs a write operation must immediately follow that command frame in the execute list buffer. Data resulting from command frames that perform CAMAC read operations is placed into the "reply list" buffer, thus generating a list of contiguous read data frames in this buffer. With this terminology fresh in mind, the process of using CAMAC command lists on the VAX boils down to a few simple operations. These are listed below. 1. Declaring a memory buffer(an array of INTEGER*2 variables) as an execute list buffer and initializing it. This operation is implemented via the CAM$DCLST procedure call. 2. Generating command frames and write data frames into an execute list buffer to perform desired CAMAC operations. Specific list operation types are discussed in the next section. 3. Executing an execute list buffer once it has been generated. This operation is implemented via the CAM$EXECUTE procedure call. 4. Accessing a data frame in the reply list resulting from the execution of an execute list to retrieve data for a given command frame. This operation is implemented via the CAM$RDATA procedure call. 5. Accessing a data frame in an execute list to modify CAMAC write data associated with a given command frame. This operation is implemented via the CAM$WDATA procedure call. VAX CAMAC SYSTEM CONCEPTS Page 2-15 2.2.4.2 List Mode Command Types There are basically three types of operations that can be performed from a CAMAC command list on the VAX system. The command types available are a function of the CAMAC highway driver hardware. These list operations represent the same CAMAC functionality as their anologous access call counterparts. Each of these calls generates a command frame in the a specified execute list buffer. No CAMAC operation is actually performed at the time of the CAMAC call, however. The command list must be executed via the CAM$EXECUTE call. The list calls for generating execute list command frames are briefly described below. 1. CAM$LPIO -Generates an execute list command frame to perform a programmed I/O operation. The subsequent execution of this command frame will have the same result as if a CAM$PIO(W) call had been executed with the same parameters. 2. CAM$LQSCAN -Generates an execute list command frame to perform a Q-Scan/Stop On Word Count operation. The subsequent execution of this command frame will have the same result as if a CAM$QSCAN((W) call had been executed with the same parameters. 3. CAM$LSTOP -Generates an execute list command frame to perform a Stop On Word Count operation. The subsequent execution of this command frame will have the same result as if a CAM$STOP(W) call had been executed with the same parameters. Detailed information on the calling sequence required for each of these procedures may be found in Appendix A. Examples demonstrating their useage may be found in chapter 7. 2.2.4.3 Random List Reference: The Frame Information Block Concept As mentioned previously, one of the operations required to conveniently utilize command lists on the VAX CAMAC system is that of accessing the information contained in a given command frame and/or data frame. One very natural method for "keying" or "indexing" command frames and/or data frames is to use the frame number. The problem with trying to do this directly is that both command frames and data frames are variable in length, thus it is very difficult to map the frame number to the appropriate offset into an execute list or a reply list without some additional information. To solve this problem and allow efficient indexing by frame number, the concept of the Frame Information Block(FIB) is introduced. The FIB is nothing more than a block of memory containing (1) the offset into an execute list where the command frame begins, (2) the VAX CAMAC SYSTEM CONCEPTS Page 2-16 length of the command frame, (3) the CAMAC function code executed by the command frame, (4) the offset into either the execute list or reply list where the data frame begins and (5) the length of the data frame. Each FIB contains exactly the same kinds of information about a given frame and hence they are all the same length. Now, if a list of FIB's is generated at the time an execute list is being built, then it becomes possible to access the command and/or data frames associated with an execute list by the frame number in a very straight forward manner. Specifically, the frame number is used to locate the FIB for that frame in the FIB list(since all FIB's are the same length, this is a matter of simple arithmetic: = ( - 1) * ). Then, having located the FIB for the frame, it is again a simple matter to determine where in the execute list the command frame begins, it's length, the disposition of any data associated with the command frame(execute list or reply list), the data frame offset in it's respective list and the data frame length. From the user's point of view, most of this detail is hidden in the list mode access procedures on the VAX. In fact, the only thing a user need do to use frame number reference is to specify a FIB list buffer(FIBL) when an execute list is declared. This FIBL then becomes the "property" of the specified execute list until the execute list buffer is declared again, at which time the list may be declared without the associated FIBL. At this point, the FIBL buffer may be used for any other purpose, because it's data is no longer relevant to the newly declared execute list. Once the FIBL is connected to an execute list, subsequent calls to generate list commands also generate FIB's in the FIBL. So, obviously, there will be as many FIB's in the FIBL as there are command frames in the execute list. A quick look at the list mode CAMAC calls for defining command frames reveals that an optional frame number may be specified. This provides a mechanism for the user to randomly update a given command frame in an execute list(provided a FIBL is connected to the execute list). The only restrictions on such random updates are (1) the CAMAC function code specified in the list mode call must be of the same class(read,write,control) as the function in the command frame, (2) the command frame generated from the list mode call must be the same length as the existing command frame and (3) the data frame size for the list mode call must be the same as the existing data frame size. Probably the most common use of the FIBL for command lists is to provide a convenient method of accessing CAMAC read data in the reply list or for updating CAMAC write data in the execute list. By using the procedures CAM$RDATA and CAM$WDATA, data for a given frame number may be extracted from the reply list into a separate buffer or inserted into the execute list from a separate buffer. It is also the case, that by understanding how to interpret the FIB fields, the user may access data directly, thus avoiding the overhead to cross load data to separate buffers. CAM$RDATA and CAM$WDATA are "security blanket" procedures. Details of and recommended methods for defining FIBL buffers in user codes can be found in chapter 7. Examples utilizing frame number reference may also be found in chapter 7. CHAPTER 3 CAMAC PROCEDURE DESCRIPTIONS At this point, a brief discussion of the calling sequences for the CAMAC access procedures is in order. The calls are divided into four basic groups for reasons of functionality and for convenience. These groups are (1) basic CAMAC access procedures, (2) CAMAC command list procedures, (3) CAMAC status procedures and (4) LAM management procedures. For each, the procedure call is defined with it's full argument list. Before getting down to the details of individual procedure calls, a few general remarks seem appropriate. These statements apply to all CAMAC access calls. 1. The argument list for a "wait I/O" version of a particular CAMAC procedure call is exactly the same as for the "proceed I/O" version of that same call. The "wait I/O" version of a particular call will always be identified by a name CAM$xxxW. The equivalent "proceed I/O" procedure call will always be indifified by a name CAM$xxx. 2. The specification of module reference mode(i.e. "direct module reference" vs. "keyed module reference") is accomplished through the use of the VAX argument descriptor mechanism. The CAMAC access procedures expect module identification to be passed by "descriptor". VAX FORTRAN has a set of rules for "passing" arguments in procedure calls based on variable type. These rules are documented in the VAX FORTRAN User's Manual. The standard mode of argument passing for a particular variable type may be explicitly declared in the procedure call by the programmer, however. FORTRAN standardly passes CHARACTER type variables by "descriptor", thus when performing a "direct module reference" CAMAC call with the CAMAC module name contained in a CHARACTER type variable, no special action is required by the programmer to force the expected calling sequence. However, FORTRAN standardly passes INTEGER*4 variables by "reference" and thus for "keyed module reference" CAMAC calls, the "descriptor" operator(%DESCR(xxx)) must be specified in the procedure call argument list to override the normal mode of passing such variables. It is the descriptor that allows the CAMAC access procedures to distinguish between the passing of a CHARACTER type variable(which implies direct module reference) and an I*4 variable(which implies keyed module reference). CAMAC PROCEDURE DESCRIPTIONS Page 3-2 3. For CAMAC acess calls where memory format control may be specified, the value 16 indicates 16-bit memory format for the transaction and the value 24 indicates 24-bit memory format for the transaction. For 16-bit format, one VAX word is required for each "count" of a CAMAC transfer, while for 24-bit format, two VAX words(or one longword) is required for each "count" of a CAMAC transfer. The memory format utilized for CAMAC I/O operations may be controlled in one of two ways. The MEM variable may be specified with each CAMAC call to explicitly declare the deasired memory format for that particular call. If the MEM variable is omitted from a particular CAMAC I/O call, the default memory format value from the CAMAC Image Block(CIB) is utilized. This default may be controlled via the CAM$CSTATE procedure call. Note that the CAM$CSTATE call is the only way to change the CIB default memory format. 4. For CAMAC access calls requiring a transfer count(TC) to be specified, the count value is assumed to be in units of the memory format associated with the call. For example, if a TC of 5 is specified and the associated memory format is 16, then 5 words will be transferred by the call. If a TC of 5 is specified and the associated memory format is 24, then 10 words(or 5 longwords) will be transferred. The transfer count is specified explicitly on all DMA/block transfer mode calls and their list mode counterparts. The transfer count has an implicit value of 1 in programmed I/O operations and is therefore not required as a call argument. 5. For CAMAC access calls where the I/O status block(IOSB) may be specified, it is assumed to be a quadword buffer(I*4 by 2 array). If the IOSB argument is explicitly specified for a particular call, that IOSB buffer will be used for that particular call only. If the IOSB argument is omitted for a particular call, a default IOSB in the CIB is used to receive CAMAC status from the the I/O request. Note that there is only one IOSB buffer in the CIB. If CAMAC calls are made from both normal program flow and AST flow, both utilizing the CIB IOSB, then the result is unpredictable. 6. For certain CAMAC calls, optional I/O synchronization parameters may be specified. They are (1) a process local event flag value(EFN), (2) an AST service procedure(FUNCTION or SUBROUTINE) and (3) a parameter value(argument) to be passed to the AST service procedure when it is called by the operating system. It is probably safe to say that most users will never find themselves in a situation where they will have to worry about utilizing these optional arguments. Such situations would arise where the application code is (1) performing CAMAC I/O operations from both normal and AST flow or (2) performing "proceed I/O" CAMAC operations and thus becoming responsible for it's own I/O synchronization. The VAX I/O system will always post a process local event flag upon the completion of an I/O request. There is no way to inhibit this. The "wait I/O" versions of the CAMAC access procedures utilize this process local event flag for I/O synchronization. In either case(wait or proceed I/O), if the EFN argument is specified on a call, that event flag value is used only on that particular call. If this argument is omitted, the default event flag value from the CIB is used. This default event flag may be controlled via the CAM$CSTATE procedure call. The AST service procedure and AST parameter value may also be specified for either wait or proceed I/O calls, however, in the case of a "wait I/O" request, specification of an AST service procedure CAMAC PROCEDURE DESCRIPTIONS Page 3-3 is rather superfluous since the I/O completion is already synchronized by the access procedure. As one last remark, a quick reference for the CAMAC procedures may be found in Appendix A. A brief description of the function of each procedure is given, along with a description of the procedure argument list. 3.1 Basic CAMAC Access Procedure Calls The CAMAC procedures described in this section constitute the core of the VAX CAMAC system. They support all of the VAX CAMAC transaction modes except for CAMAC command lists. In addition, several support procedures are also described. The procedures that actually perform CAMAC I/O operations are listed briefly below, followed by a discussion of the common argument list utilized by these procedure calls. CAM$PIO(W)(MOD_DESCR,A,F[,DATA][,MEM][,IOSB][,EFN][,AST][,ASTP]) -Perform a single-action CAMAC request(programmed I/O). CAM$QSCAN(W)(MOD_DESCR,A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) -Perform a Q-Scan/Stop On Word Count CAMAC transaction. CAM$QSTOP(W)(MOD_DESCR,A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) -Perform a Q-Stop/Stop On Word Count CAMAC transaction. CAM$STOP(W)(MOD_DESCR,A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) -Perform a Stop On Word Count CAMAC transaction. As may be observed from the above procedure calls, the argument lists are essentially the same, independent of the particular call being made. In fact, the programmed I/O call is the only one differing. It lacks the transfer count argument(for reasons discussed in the general remarks at the beginning of this chapter). A brief description of the individual arguments follows. MOD_DESCR is the descriptor associated with the ASCII CAMAC logical modula name or the module key value assigned via the CAM$ASSIGN procedure call. %DESCR is the normal mode for CHARACTER variable types generated by the VAX FORTRAN compiler. %DESCR must be forced for all other variable types. A is a BYTE, I*2, I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. TC is an I*2, I*4 variable containing the desired transfer count value. Remember the transfer count is in units of the associated memory format for the call(i.e. 1 transfer = 1 I*2 element if MEM=16 is used, 1 transfer = 1 I*4 element if MEM=24 is used). CAMAC PROCEDURE DESCRIPTIONS Page 3-4 DATA is a buffer containing/to receive CAMAC data. The data buffer may be of any type as long as it is passed by reference. The most natural data buffer declarations are INTEGER*2 for buffers containing/to receive data associated with MEM=16 operations, INTEGER*4 for buffers containing/to receive data associated with MEM=24 operations. MEM is a BYTE, I*2, I*4 variable specifying the desired memory format for the CAMAC transaction. If MEM=16, the transaction uses 16-bit memory format. If MEM=24, the transaction uses 24-bit memory format. If the MEM argument is not specified or specified as a null parameter, the default memory format from the CIB is used for the transaction. IOSB is a quadword(8 byte) buffer to receive I/O status resulting from the execution of the CAMAC transaction. If not specified or specified as a null argument, the default IOSB in the CIB is used for the transaction. EFN is the value of a process local event flag to be posted when the CAMAC I/O operation is complete. Note that this argument is assumed to be passed by value(i.e. by using the %VAL operator). If not specified, the default EFN from the CIB is used for this I/O request. A process local event flag will always be posted for each CAMAC I/O request. CAM$xxW calls wait for the event flag to be posted before returning to the calling program. AST is the name of a procedure to be called to service an I/O completion AST as a means of signaling that a specific CAMAC I/O request has been completed. This AST service procedure may be written as a SUBROUTINE or FUNCTION subprogram, although, the function value returned from such a call can not be referenced by the main program flow. ASTP is the value of a parameter to be passed to the AST service procedure when it is called to signal the completion of this specific CAMAC I/O request. Note that this argument is assumed to be passed by value(i.e. by using the %VAL operator). There are two support procedures closely related to the access procedures described above. These procedures perform the functions of (1) key assignment and (2) key deassignment. CAM$ASSIGN(MOD_NAME,MOD_KEY) where MOD_NAME is a CHARACTER type variable containing the logical module name for the CAMAC module for which the key is to be assigned. MOD_KEY is an I*4 variable to receive the key value assigned to the logical CAMAC module. CAM$DASSGN(MOD_KEY) To close out this section, the calling sequence of the support procedure that allows certain CAMAC Image Block default values to be modified is simply stated for completeness. A description of the arguments associated with this call may be found in Appendix A. CAM$CSTATE(EFN,XSTATE,QSTATE,MEM) CAMAC PROCEDURE DESCRIPTIONS Page 3-5 3.2 CAMAC Command List Procedures This section describes those VAX CAMAC procedures associated with the generation, manipulation and execution of CAMAC command lists. A typical scenario for a CAMAC command list would be 1. Declare an execute list buffer via the CAM$DCLST procedure call then, 2. Generate execute list command frames using the CAM$LPIO, CAM$LQSCAN and CAM$LSTOP procedure calls then, 3. Utilize the CAM$WDATA procedure call to update dynamic CAMAC write data for specific command frames in the execute list then, 4. Execute the CAMAC command list then, 5. Utilize the CAM$RDATA procedure call to extract CAMAC read data for a specific command frame from the reply list buffer then, 6. Either execute the list again for the next data acquisition/control cycle or begin again with step 1 to perform a different sequence of CAMAC operations. As mentioned above, the execute list buffer is declared via the CAM$DCLST procedure call. This call initializes the execute list buffer header, a data structure imbedded at the beginning of the execute list buffer containing information utilized and maintained by the list access procedures. Once initialized, command and CAMAC write data frames may be inserted into the execute list buffer. The calling sequence for CAM$DCLST is as follows: CAM$DCLST(EXE_LST,EXE_LEN[,MEM][,FIBL]) where EXE_LST is an I*2 array to be used as the CAMAC execute(command) list. EXE_LEN is an I*2, I*4 variable containing the length of the execute list buffer in units of I*2 elements. MEM is a BYTE, I*2, I*4 variable specifying the memory format to be used for the execute list. If not specified or specified as a null argument, the default memory format from the CIB is used. FIBL is an I*2 array(4 X EXE_MAXCMD) to be used as the Frame Information Block list for the execute list buffer. The calling sequences for the procedures generating execute list command frames bear close resemblance to the CAMAC I/O procedures described in the last section. The command frame generation procedures are listed below. CAM$LPIO(EXE_LST,MOD_DESCR,A,F,[,DATA][,FRAME]) CAMAC PROCEDURE DESCRIPTIONS Page 3-6 -Inserts a single-action(programmed I/O) command frame into the specified execute list buffer. CAM$LQSCAN(EXE_LST,MOD_DESCR,A,F,TC[,DATA][,FRAME]) -Inserts a Q-Scan/Stop On Word Count command frame into the specified execute list buffer. CAM$LSTOP(EXE_LST,MOD_DESCR,A,F,TC[,DATA][,FRAME]) -Inserts a Stop On Word Count command frame into the specified execute list buffer. Many of the arguments to the list command procedures are exactly the same as the arguments to the CAMAC access procedures described in the previous section. Only those arguments unique to the list access procedures are described here. EXE_LST is an I*2 array previously declared as an execute list buffer via the CAM$DCLST procedure call. FRAME is an I*2, I*4 variable containing the number of an existing list command frame to be updated by this command request. If specified, the corresponding frame in the execute list is modified with the module data, subaddress, function code and write data as specified in the call. Note that this random list update is not allowed if the resulting command frame or data frame is different in length from the existing comand or data frames nor is it allowed if the function code specified in the call is not of the same class(read,write,control) as the function code in the existing frame. The CAMAC command list may be executed via the CAM$EXECUTE(W) procedure call. The calling sequence for this procedure is as follows. CAM$EXECUTE(W)(EXE_LST,[REP_LST,REP_LEN][,IOSB][,EFN][,AST][,ASTP]) where EXE_LST is as defined above. REP_LST is an I*2 array sufficient in length to receive the CAMAC read data resulting from the execution of the specified execute list. REP_LEN is an I*2, I*4 variable containing the length of the reply list buffer in units of I*2 elements. IOSB, EFN, AST, ASTP are as defined in the previous section. The data frame in the execute list corresponding to a command frame may be dynamically updated using the frame number for reference via the CAM$WDATA procedure call. The data frame resulting from the execution of a specific command frame in the execute list may be extracted from the reply list buffer using the frame number for reference via the CAM$RDATA procedure call. These calls are defined as follows. CAMAC PROCEDURE DESCRIPTIONS Page 3-7 CAM$WDATA(EXE_LST,FRAME,WRITE_DATA) where EXE_LST is a valid execute list buffer. FRAME is an I*2, I*4 variable containing the number of an execute list command frame that performs a CAMAC write operation. WRITE_DATA is an I*2, I*4 array of data to be used to update the write data frame corresponding to the specified frame number. The number of words transferred from the buffer into the execute list is determined by the CAM$WDATA procedure from the FIB for the specified frame. It is the caller's responsibility to insure that the specified buffer contains sufficient data to fill the data frame associated with the specified frame number. CAM$RDATA(EXE_LST,FRAME,REP_LST,READ_DATA) where EXE_LST is a valid execute list buffer. FRAME is an I*2, I*4 variable containing the number of an execute list command frame that performs a CAMAC read operation. REP_LST is an I*2 array containing CAMAC read data resulting from the execution of the specified execute list. READ_DATA is an I*2, I*4 array to receive the data frame corresponding to the specified frame number from the specified reply list buffer. The CAM$RDATA procedure determines the number of words to transfer from the reply list from the FIB associated with the specified frame number. It is the caller's responsibility to insure that this buffer is sufficient in size to receive the data frame associated with the specified frame number. 3.3 CAMAC Status Procedures This section describes a collection of procedures designed to assist the user to test status returned from the execution of a CAMAC I/O request via the CAMAC I/O status block. These procedures should be viewed as a set of tools from which application dependent error handling and analysis procedures may be constructed. In many instances these procedures themselves will suffice for error handling. The following procedures perform CAMAC I/O status analysis and display functions on behalf of the caller. The procedures CAM$ERROR, CAM$X, CAM$Q and CAM$XANDQ should be treated as LOGICAL functions when called. They all accept as an optional input argument an IOSB buffer. If not specified or specified as a null argument, the CAMAC Image Block(CIB) IOSB is used. CAM$ERROR(EXP_X,EXP_Q[,IOSB]) -Analyzes the CAMAC I/O status block for an anomolous termination of the CAMAC I/O request. The expected X response may be specified by the EXP_X CAMAC PROCEDURE DESCRIPTIONS Page 3-8 variable. This argument may be specified as a null argument, in which case the X response is not checked. Similarly, the expected Q response may be specified by the XEP_Q variable. The return value is .TRUE. if an anomolous(or unexpected) condition is detected, .FALSE. otherwise. CAM$X([IOSB]) -Analyzes the CAMAC I/O status block for the X response and returns a value of .TRUE. if X=1, .FALSE. otherwise. CAM$Q([IOSB]) -Analyzes the CAMAC I/O status block for the Q response and returns a value of .FALSE. if Q=1, .FALSE. otherwise. CAM$XANDQ([IOSB]) -Equivalent to the logical expression (CAM$X([IOSB]) .AND. CAM$Q([IOSB])). CAM$SHOW_STAT([IOSB]) -Analyzes, formats and displays the contents of the CAMAC I/O status block to the logical device SYS$OUTPUT. Finally, a means to sample the CAMAC Image Block IOSB is provided in the CAM$GET_STAT procedure call. The call has one argument, consisting of a quadword(8 byte) buffer to receive a copy of the CIB IOSB contents. The call format is as follows. CAM$GET_STAT(IOSB) 3.4 CAMAC LAM Management Procedures This section describes those procedures associated with LAM management services in the VAX CAMAC system. These procedures offer two basic levels of functionality for the VAX CAMAC user. Users may chose to associate an AST service procedure with a LAM from a particular CAMAC module, handling the LAM in a manner analogous to servicing a device interrupt or they may suspend the execution of the program until the LAM from a particular module is recognized by the CAMAC system. The LAM AST procedures have very similar argument lists. These procedures calls are listed and described below. CAM$LAMAST(MOD_DESCR,LAM_AST,LAM_ASTP[,IOSB][,EFN][,AST][,ASTP]) -Set a LAM AST request for the specified CAMAC module. CAM$CANLAM(MOD_DESCR,[,IOSB][,EFN][,AST][,ASTP]) -Cancel a previously requested LAM AST for the specified CAMAC module. where MOD_DESCR is the descriptor of the logical CAMAC module name or the CAMAC module key(see description in the first section of this chapter). CAMAC PROCEDURE DESCRIPTIONS Page 3-9 LAM_AST is the name of an LAM AST service procedure called when the LAM is recognized by the CAMAC system. LAM_ASTP is the value of an 32-bit(I*4) parameter to be passed to the LAM AST service procedure. Note argument is assumed to be passed by value. IOSB, EFN, AST and ASTP are as previously defined. The LAM wait procedure call is much simpler in format, only requiring two arguments. This call is defined as follows. CAM$LAMWAIT(MOD_DESCR,TIME_OUT) where MOD_DESCR is as defined above. TIME_OUT is an I*2, I*4 variable containing the maximum time to wait for the LAM to be asserted before resuming execution. This value is assumed to be in units of seconds. CHAPTER 4 FUNDAMENTAL CAMAC EXAMPLES This chapter contains a number of sample program sequences demonstrating the use of the fundamental CAMAC access procedures, as well as standard error checking techniques that can(and by all means should) be used with these procedure calls. The principal CAMAC I/O calls demonstrated in this chapter include CAM$PIO(W) and CAM$STOP(W). It is very likely that these calls will satisfy the requirements of most CAMAC system user's, although, the serious applications programmer should become familiar with the more powerful CAMAC modes available on the VAX system so that they can be utilized where applicable. In any case, these two CAMAC I/O calls represent the place to start in order to become familiar with the VAX CAMAC system. 4.1 A Programmed I/O Example Using CAM$PIOW The first example program considered in this chapter demonstrates the most simple CAMAC call that can be performed, the CAM$POIW call. This program is a simple, single module CAMAC exercisor for use with the FED VAX CAMAC system. The program enables the user to specify the logical module to be exercised and then enters a subaddress, function code request loop enabling a sequence of CAMAC transactions to the module. Each transaction is performed as a single-action CAMAC request(non-DMA type operation). Following the execution of the CAMAC request, the X and Q responses are displayed as logical outputs(T/F). If the CAMAC function code indicates a data write operation, the user is prompted for input(hexadecimal format) before the operation takes place. If the CAMAC function code indicates a data read operation, the resulting data is displayed following the X and Q status display. To exit the (A,F) loop, a '-1' subaddress or function code may be entered. Upon such input, the user is prompted for another CAMAC module name to exercise. A carriage return will cause the program to exit. program testpio implicit integer(a-z) character logmod*32 logical*4 cam$error,cam$x,cam$q logical*4 xval,qval type *,'VAX CAMAC Module Exercisor' c++ c c Prompt user for logical module name. c c-- 1001 continue FUNDAMENTAL CAMAC EXAMPLES Page 4-2 type 1999 1999 format(1x,'Enter module name ',$) accept 1998,loglen,logmod 1998 format(q,a32) if (loglen.eq.0) call exit c++ c c Subaddress, function code repetition loop. c c-- 2001 continue type 1996 1996 format(1x,'Enter subaddress, function code',$) accept 1995,a,f 1995 format(2i) c++ c c Check for subaddress(A) or function(F) negative. If so, c exit the (subaddress, function) repetition loop to prompt c the user for some other logical module to exercise. c c-- if (a.lt.0 .or.f.lt.0) then go to 1001 end if c++ c c Prompt for data if the function code indicates a C CAMAC write operation. c c-- if (f.ge.16 .and. f.le.23) then type 1994 accept 1993,data end if 1994 format(1x,'Enter write data(z format)',$) 1993 format(z) c++ c c Perform a single-action CAMAC I/O request via the c CAM$PIOW call. Things to note about this call. c 1. This call uses direct module reference as c opposed to keyed module reference. c 2. '24' bit mode is always specified to override c the CAMAC image block default of '16' bit mode. c 3.The CAMAC image block IOSB is used by this request. c c-- status=cam$piow(logmod(1:loglen),a,f,data,24) c++ c c Check for any errors in executing the CAMAC I/O request. c 1. Check if an error was detected while trying c to generate the I/O request to the CAMAC I/O c driver. The function value returned from the c CAM$PIOW call will indicate this. If so, signal c with the error status code and take appropriate FUNDAMENTAL CAMAC EXAMPLES Page 4-3 c action. c 2. From here, use the CAM$ERROR function to check c the CAMAC IOSB for any CAMAC error. Note that the c specification of the argument as "null" causes the c IOSB in the CAMAC image block to be checked. c 3. If CAM$ERROR returns a .TRUE. indication, display c the IOSB error information via the CAM$SHOW_STAT c procedure call and take appropriate action. c 4. If CAM$ERROR returns a .FALSE. indication, continue. c c-- if (.not.status) then call lib$signal(%val(status)) go to 1001 end if if (cam$error(.true.,)) then call cam$show_stat(iosb) go to 1001 end if c++ c c Display the CAMAC X and Q status from the request. c c-- xval=cam$x() qval=cam$q() type 1989,xval,qval 1989 format(1x,'X =',l,' Q=',l) c++ c c If the CAMAC function indicates a read operation and the c module executed the command(X=.TRUE.), then display the c data value returned from the module. c c-- if (xval .and. f.le.7) then type 1991,data end if 1991 format(1x,'Read data=',z8) go to 2001 end 4.2 A Stop Mode Example Using CAM$STOPW Now that you've had some time to become acquainted with a simple CAMAC example, let's upgrade the previous example to produce a CAMAC module exercisor capable of performing Stop mode DMA/block transfers to or from a CAMAC memory module. At the same time, some more sophisticated techniques are also demonstrated. This program is designed to demonstrate the STOP mode CAMAC access call in the VAX CAMAC library. The program utilizes a Le Croy Systems 8801/16 memory moduule. The program prompts the user for the logical module name and desired transfer size. It then initializes the LRS 8801 module and enters a loop to write a dynamically generated data buffer to the module, read it back and verify the contents. Any CAMAC errors cause the program to exit the main test loop, prompting for direction. FUNDAMENTAL CAMAC EXAMPLES Page 4-4 program l8801m3 implicit integer(a-z) c++ c c Program parameters c c-- parameter maxb=4096 ! maximum buffer length parameter max16=maxb/2 ! as i*2 elements parameter mem_w=16 ! CAMAC memory format=16 bit parameter mem_l=24 ! CAMAC memory format=24 bit c++ c c Input and output buffer definitions c c-- integer*2 caminp(max16),camout(max16) c++ c c Use CHARACTER variables for logical CAMAC module names. c They represent a very convenient way to handle ASCII text c strings on the VAX system. c c-- character logmod*32 c++ c c Misc. declarations c c-- logical*4 cam$go data map/0/ type *,'LRS 8801 CAMAC Memory Module Exercisor' c c Prompt user for logical module name. c c-- type 1999 1999 format(1x,'Enter LRS 8801 module name ',$) accept 1998,loglen,logmod 1998 format(q,a32) if (loglen.eq.0) call exit c++ c c Assign key to module for keyed access. c c-- status=cam$assign(logmod,keyv) if (.not.status) then call lib$stop(%val(status)) end if type 1985,logmod(1:loglen),keyv 1985 format(1x,'Module name: ',a,' Key value=',z8) c++ c c Prompt user for desired transfer count. c FUNDAMENTAL CAMAC EXAMPLES Page 4-5 c-- 3001 continue type 1995,max16 1995 format(1x,'Enter transfer count;',i,' Limit= ',$) accept *,tc if (tc.le.0 .or. tc.gt.max16) then type *,'Invalid transfer count=',tc go to 3001 end if c++ c c Clear LRS 8801 memory module. c c-- a=0 f=9 status=cam$piow(%descr(keyv),a,f) if (.not.cam$go(status,)) then call exit end if c++ c c Disable LRS 8801 external memory port. c c-- f=19 status=cam$piow(%descr(keyv),a,f,0,mem_l) if (.not.cam$go(status,)) then call exit end if c++ c c Enable auto-incrememt mode for LRS 8801 MAP. c c-- f=25 status=cam$piow(%descr(keyv),a,f) if (.not.cam$go(status,)) then call exit end if c++ c c LRS 8801 Stop mode test loop. c c-- 4001 continue c++ c c Generate alternating data pattern for c LRS 8801 test. c c-- call gen16(camout,tc) c++ c C Set LRS 8801 MAP to initial value. c FUNDAMENTAL CAMAC EXAMPLES Page 4-6 c-- f=18 status=cam$piow(%descr(keyv),a,f,map,mem_l) if (.not.cam$go(status,)) then call exit end if c++ c c Write data buffer to LRS 8801 using Stop mode c CAMAC request. Note the following about this c request: c 1. It uses keyed module reference as opposed c to direct module reference. c 2. It uses the user defined I/O status block buffer. c c-- f=16 status=cam$stopw(%descr(keyv),a,f,tc,camout,mem_w) if (.not.cam$go(status,)) then call exit end if c++ c c Reset LRS 8801 MAP to read back data. c c-- f=18 status=cam$piow(%descr(keyv),a,f,map,mem_l) if (.not.cam$go(status,)) then call exit end if c++ c c Prime the LRS 8801 for the block read. c c-- f=2 status=cam$piow(%descr(keyv),a,f,dumy,mem_w) if (.not.cam$go(status,)) then call exit end if c++ c c Read back data buffer written to LRS 8801 module c using the Stop mode CAMAC request. c c-- status=cam$stopw(%descr(keyv),a,f,tc,caminp,mem_w) if (.not.cam$go(status,)) then call exit end if c++ c c Verify that the data read matches the data written. c c-- call ver16(caminp,camout,tc) FUNDAMENTAL CAMAC EXAMPLES Page 4-7 go to 4001 end logical function cam$go(status,iosb) implicit integer(a-z) integer*4 iosb(*),liosb(2) logical*4 cam$error character response*4 c++ c c Assume failure by setting 'GO' false. c c-- cam$go=.false. c++ c c Test return system status from CAMAC call. c If failure indicated, signal condition and c go prompt for action if control returns. c c-- if (.not.status) then call lib$signal(%val(status)) go to 1001 end if c++ c c If the IOSB is specified as a null parameter, then sample the c CAMAC image block IOSB, else, use the specified IOSB. c c-- if (%loc(iosb).eq.0) then call cam$get_stat(liosb) else liosb(1)=iosb(1) liosb(2)=iosb(2) end if c++ c c If system status is normal, then test for CAMAC errors. c If CAMAC errors, display CAMAC I/O status block and c go prompt for action. c c-- if (cam$error(.true.,,liosb)) then call cam$show_stat(liosb) go to 1001 end if c++ c c Change assumed failure to success and return. c c-- cam$go=.true. return c++ c c Prompt for manual failure override. FUNDAMENTAL CAMAC EXAMPLES Page 4-8 c c-- 1001 continue type 1999 1999 format(1x,'Override Failure? y/[n] ',$) accept 1998,resp_len,response 1998 format(q,a) if (resp_len.eq.1 .and. 9 (response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y')) cam$go =.true. return end subroutine gen16(camout,tc) implicit integer(a-z) integer*2 camout(*) integer*2 tpat16/'3333'x/ c++ c c Generate test data buffer from 16-bit test pattern c then replace the test pattern with it's ones complement. c c-- do tndx=1,tc camout(tndx)=tpat16 end do tpat16=-tpat16-1 return end subroutine ver16(caminp,camout,tc) implicit integer(a-z) integer*2 caminp(*),camout(*) c++ c c Verify the 16-bit input data buffer with the 16-bit c output buffer for the length specified by the transfer c count. The verification stops at the first data mismatch c encountered. c c-- do tndx=1,tc if (caminp(tndx).ne.camout(tndx)) then type 1999,tndx,camout(tndx),caminp(tndx) return end if end do 1999 format(1x,'Pos=',i,' Output=',z4,' Input=',z4) return end CHAPTER 5 ADVANCED CAMAC EXAMPLES This chapter demonstrates a number of more advanced CAMAC operations, primarily dealing with the Q-Scan and Q-Stop techniques. Also, an example demonstrating the use of "proceed I/O" operations on the VAX CAMAC system is included. It is assumed at this point that the reader has some understanding of these more advanced operations and techniques, either from reading chapter 2 or some other source. If not, reading chapter 2 is advisable before continuing. 5.1 A CAMAC Q-Scan Example Using CAM$QSCANW This program is designed to demonstrate the Q-SCAN CAMAC access call in the VAX CAMAC library. The program utilizes a Le Croy Systems 2551 12-channel scaler for this example. The program prompts the user for the logical module name. Then the LRS 2551 module is initialized and the program enters a test loop. The test loop increments all 12 channels of the scaler via a module control function, reads the 12 scaler channels using 24 bit memory format and verifies the count in each channel with the expected count. If any CAMAC errors are detected, the user is prompted for an action response. program l2551 implicit integer(a-z) c++ c c Define program parameters c c-- parameter l2551_nchan=12 ! maximum LRS 2551 channel parameter mem_l=24 ! memory format= 24 bit c++ c c Input data buffer for LRS 2551 c c-- integer*4 l2551_data(l2551_nchan) c++ c c Use a CHARACTER variable for the logical module name c c-- character logmod*32 type *,'LRS 2551 Module Exercisor' c++ ADVANCED CAMAC EXAMPLES Page 5-2 c c Set default CAMAC state for event flag and memory format. c c-- status=cam$cstate(%val(0),,,mem_l) if (.not.status) then call lib$stop(%val(status)) end if c++ c c Prompt user for logical module name. c c-- type 1999 1999 format(1x,'Enter LRS 2551 module name ',$) accept 1998,loglen,logmod 1998 format(q,a) if (loglen.eq.0) call exit c++ c c Assign key to module for keyed module reference. c c-- status=cam$assign(logmod(1:loglen),keyv) if (.not.status) then call lib$stop(%val(status)) end if c++ c c Initialize counter and the LRS 2551 scaler. c c-- countl=0 a=0 f=9 status=cam$piow(%descr(keyv),a,f) if (.not.cam$go(status,)) then call exit end if c++ c c Q-Scan test loop. c c-- 1001 continue c++ c c Increment all 12 channels by 1 count. c c-- f=25 status=cam$piow(%descr(keyv),a,f) if (.not.cam$go(status,)) go to 1001 countl=countl+1 c++ c c Perform a Q-Scan request to read back all 12 channels. ADVANCED CAMAC EXAMPLES Page 5-3 c Note that this CAMAC request c 1. Uses keyed module reference vs. direct module c reference. c 2. Uses the I/O status block in the CAMAC image block. c 3. Uses the default memory format from the CAMAC image c block(specified above via CAM$CSTATE). c c-- f=0 status=cam$qscanw(%descr(keyv),a,f,l2551_nchan,l2551_data) if (.not.cam$go(status,)) go to 1001 c++ c c Verify all channels of data read from the LRS 2551. c c-- call verify(countl,l2551_data,l2551_nchan) go to 1001 end logical function cam$go(status,iosb) implicit integer(a-z) integer*4 iosb(*),liosb(2) logical*4 cam$error character response*4 c++ c c Assume failure by setting 'GO' false. c c-- cam$go=.false. c++ c C Test return status from CAMAC call. If failure indicated, c signal condition and prompt for action if control returns c after signal. c c-- if (.not.status) then call lib$signal(%val(status)) go to 1001 end if c++ c c If IOSB parameter specified as null, then sample the CAMAC c image block IOSB. c-- if (%loc(iosb).eq.0) then call cam$get_stat(liosb) else liosb(1)=iosb(1) liosb(2)=iosb(2) end if c++ c c Test for any CAMAC errors. If so, then display nature of c the CAMAC error via CAM$SHOW_STAT and prompt for action. c ADVANCED CAMAC EXAMPLES Page 5-4 c-- if (cam$error(.true.,,liosb)) then call cam$show_stat(liosb) go to 1001 end if c++ c c Change assumed failure to success and return. c c-- cam$go=.true. return c++ c c Prompt for failure override response. c c-- 1001 continue type 1999 1999 format(1x,'Override Failure? Y/[N] ',$) accept 1998,resp_len,response 1998 format(q,a) if (resp_len.eq.1 .and. 9 (response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y')) cam$go=.true. return end subroutine verify(countl,datal,nchan) implicit integer(a-z) integer*4 datal(*) c++ c c Verify all channels of data in the input buffer(datal) aganist the c expected count value(countl). Data from a channel failing to match c is displayed. c c-- do i=1,nchan if (countl.ne.datal(i)) then type 1999,i,countl,datal(i) return end if 1999 format(1x,'Mismatch: Chan=',i,2x,i,' Expected; ',i,' Read') end do return end ADVANCED CAMAC EXAMPLES Page 5-5 5.2 A Q-Stop Mode Example Using CAM$QSTOP This program is designed to demonstrate the Q-Stop CAMAC access call in the VAX CAMAC library. The program utilizes a modified Le Croy Systems 8801/16 memory module. The module modifications correct a design flaw in the module enabling it to post Q responses when being read. This fact does not invalidate the generality of this example. Note that this is basically the same program as used to demonstrate the Stop mode CAMAC call. The new wrinkles added to this rendition of the previous example include (1) the obvious use of the Q-Stop CAMAC call and (2) the fact that the program uses the proceed I/O versions of the CAMAC calls. program l8801m2 implicit integer(a-z) c++ c c Note: Procedure names used as arguments in procedure calls c must be declared as external symbols in the calling program. c Otherwise, the FORTRAN compiler will mistake the symbol for c a variable name in the calling procedure. c c-- external lrs_ast c++ c c Program parameters c c-- parameter maxb=4096 ! maximum buffer length parameter max16=maxb/2 ! as i*2 elements parameter mem_w=16 ! CAMAC memory format=16 bit parameter mem_l=24 ! CAMAC memory format=24 bit parameter lrs_maxio=5 ! max proceed I/O sequence length parameter lrs_efn=1 ! process local efn for CAMAC c++ c c Define an I/O status block list to allow a common c AST procedure to service the I/O completion c AST's resulting from the CAMAC I/O calls. c c-- common/lrs_iosb/ camiosb(2,lrs_maxio) parameter iosb_wmap=1 ! write LRS 8801 map(for write) parameter iosb_wdat=2 ! write LRS 8801 data parameter iosb_rmap=3 ! write LRS 8801 map(for read) parameter iosb_prdat=4 ! prime block read pio parameter iosb_rdat=5 ! read LRS 8801 data c++ c c Input and output buffer definitions c c-- integer*2 caminp(max16),camout(max16) c++ c c Use CHARACTER variables for logical CAMAC module names. c They represent a very convenient way to handle ASCII text ADVANCED CAMAC EXAMPLES Page 5-6 c strings on the VAX system. c c-- character logmod*32 c++ c c Misc definitions c c-- logical*4 cam$go data map/0/ type *,'LRS 8801 CAMAC Memory Module Exercisor' c++ c c Enable AST delivery for the process. c Note: This system service call is necessary to allow any c AST's to be delivered to the process executing this image. c c-- call sys$setast(%val(1)) c++ c c Prompt user for logical module name. c c-- type 1999 1999 format(1x,'Enter LRS 8801 module name ',$) accept 1998,loglen,logmod 1998 format(q,a32) if (loglen.eq.0) call exit c++ c c Assign key to module for keyed access. c c-- status=cam$assign(logmod,keyv) if (.not.status) then call lib$stop(%val(status)) end if type 1985,logmod(1:loglen),keyv 1985 format(1x,'Module name: ',a,' Key value=',z8) c++ c c Prompt user for desired transfer count. c c-- 3001 continue type 1995,max16 1995 format(1x,'Enter transfer count;',i,' Limit ',$) accept *,tc if (tc.le.0 .or. tc.gt.max16) then type *,'Invalid transfer count=',tc go to 3001 end if c++ c c Clear LRS 8801 memory module. ADVANCED CAMAC EXAMPLES Page 5-7 c c-- a=0 f=9 status=cam$piow(%descr(keyv),a,f) if (.not.cam$go(status,)) then call exit end if c++ c c Disable LRS 8801 external memory port. c c-- f=19 status=cam$piow(%descr(keyv),a,f,0,mem_l) if (.not.cam$go(status,)) then call exit end if c++ c c Enable auto-incrememt mode for LRS 8801 MAP. c c-- f=25 status=cam$piow(%descr(keyv),a,f) if (.not.cam$go(status,)) then call exit end if c++ c c LRS 8801 Q-Stop mode test loop. c c-- 4001 continue c++ c c Generate alternating data pattern for c LRS 8801 test. c c-- call gen16(camout,tc) c++ c c Set LRS 8801 MAP to initial value. c c-- f=18 status=cam$pio(%descr(keyv),a,f,map,mem_l, 9 camiosb(1,iosb_wmap),%val(lrs_efn),lrs_ast,iosb_wmap) if (.not.status) then call lib$signal(%val(status)) go to 4001 end if c++ c c Write data buffer to LRS 8801 using Q-Stop mode c CAMAC request. Note the following about this ADVANCED CAMAC EXAMPLES Page 5-8 c request: c 1. It uses keyed module reference as opposed c to direct module reference. c 2. It uses the user defined I/O status block buffer. c c-- f=16 status=cam$qstop(%descr(keyv),a,f,tc,camout,mem_w, 9 camiosb(1,iosb_wdat),%val(lrs_efn),lrs_ast,iosb_wdat) if (.not.status) then call lib$signal(%val(status)) go to 4001 end if c++ c c Reset LRS 8801 MAP to read back data. c c-- f=18 status=cam$pio(%descr(keyv),a,f,map,mem_l, 9 camiosb(1,iosb_rmap),%val(lrs_efn),lrs_ast,iosb_rmap) if (.not.status) then call lib$signal(%val(status)) go to 4001 end if c++ c c Prime the LRS 8801 for the block read. c c-- f=2 status=cam$pio(%descr(keyv),a,f,dumy,mem_w, 9 camiosb(1,iosb_prdat),%val(lrs_efn),lrs_ast,iosb_prdat) if (.not.status) then call lib$signal(%val(status)) go to 4001 end if c++ c c Read back data buffer written to LRS 8801 module c using the Q-Stop mode CAMAC request. c c-- status=cam$qstop(%descr(keyv),a,f,tc,caminp,mem_w, 9 camiosb(1,iosb_rdat),%val(lrs_efn),lrs_ast,iosb_rdat) if (.not.status) then call lib$signal(%val(status)) go to 4001 end if c++ c c Wait here for all I/O completion AST's to be delivered. The last c in the sequence will request a wakeup for the process, allowing c the verification to take place. c c-- call sys$hiber ADVANCED CAMAC EXAMPLES Page 5-9 c++ c c Verify that the data read matches the data written. c c-- call ver16(caminp,camout,tc) go to 4001 end subroutine lrs_ast(lrs_seq) implicit integer(a-z) parameter lrs_maxio=5 ! max proceed i/o count common/lrs_iosb/ camiosb(2,lrs_maxio) c++ c c Use sequence number passed as AST parameter to verify IOSB c success or failure. c c-- if (cam$error(.true.,,camiosb(1,lrs_seq))) then call cam$show_stat(camiosb(1,lrs_seq)) call exit end if c++ c c Check if the sequence number for the completed operation indicates c the last in the sequence and if so, trigger the wakeup request for c the process. c c-- if (lrs_seq.eq.lrs_maxio) then status=sys$wake(,) if (.not.status) then call lib$stop(%val(status)) end if end if return end logical function cam$go(status,iosb) implicit integer(a-z) integer*4 iosb(*),liosb(2) logical*4 cam$error character response*4 c++ c c Assume failure by setting 'GO' false. c c-- cam$go=.false. c++ c c Test return system status from CAMAC call. c If failure indicated, signal condition and c go prompt for action if control returns. c c-- if (.not.status) then call lib$signal(%val(status)) ADVANCED CAMAC EXAMPLES Page 5-10 go to 1001 end if c++ c c If a null IOSB was specified for the call, sample the CAMAC image c block IOSB, else, use the specified IOSB. c c-- if (%loc(iosb).eq.0) then call cam$get_stat(liosb) else liosb(1)=iosb(1) liosb(2)=iosb(2) end if c++ c c If system status is normal, then test for CAMAC errors. c If CAMAC errors, display CAMAC I/O status block and c go prompt for action. c c-- if (cam$error(.true.,,liosb)) then call cam$show_stat(liosb) go to 1001 end if c++ c c Change assumed failure to success and return. c c-- cam$go=.true. return c++ c c Prompt for manual failure override. c c-- 1001 continue type 1999 1999 format(1x,'Override Failure? Y/[N] ',$) accept 1998,resp_len,response 1998 format(q,a) if (resp_len.eq.1 .and. 9 (response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y')) cam$go =.true. return end subroutine gen16(camout,tc) implicit integer(a-z) integer*2 camout(*) integer*2 tpat16/'3333'x/ c++ c c Generate test data buffer from 16-bit test pattern c then replace the test pattern with it's ones complement. c c-- ADVANCED CAMAC EXAMPLES Page 5-11 do tndx=1,tc camout(tndx)=tpat16 end do tpat16=-tpat16-1 return end subroutine ver16(caminp,camout,tc) implicit integer(a-z) integer*2 caminp(*),camout(*) c++ c c Verify the 16-bit input data buffer with the 16-bit c output buffer for the length specified by the transfer c count. The verification terminates at the first data c mismatch encountered. c c-- do tndx=1,tc if (caminp(tndx).ne.camout(tndx)) then type 1999,tndx,camout(tndx),caminp(tndx) return end if end do 1999 format(1x,'Pos=',i,' Output=',z4,' Input=',z4) return end CHAPTER 6 LAM SERVICE EXAMPLES This chapter deals with the LAM service procedure calls in the VAX CAMAC library. A number of examples are presented demonstrating the use of these procedures. 6.1 A LAM Wait Example Using CAM$LAMWAIT This program demonstrates the use of the CAMAC LAM wait access procedure(CAM$LAMWAIT). The LAM wait procedure performs several system and CAMAC service calls on behalf of the user. The detailed flow of this procedure is described in Appendix A of this manual.The program assumes a LAM source is avaliable, such as a Jorway Manual Input Module. program lamtest implicit integer(a-z) c++ c c CAM$LAMWAIT returns a system status code as a function c value(just like all of the other CAMAC access procedures). c The code 'SS$_WASSET' is returned if the LAM wait is satisfied c within the specified time interval, 'SS$_WASCLR' is returned c if the LAM wait is not satisfied. Other system status codes may c be returned as indications of other failure conditions. c c-- external ss$_wasset,ss$_wasclr c++ c c Parameter definitions c c-- parameter time_out=5 ! time out value(sec) c++ c c Use a CHARACTER variable for the logical module name. c c-- character logmod*32,response*4 c++ c c Prompt for logical module name. c LAM SERVICE EXAMPLES Page 6-2 c-- 1001 continue type 1999 1999 format(1x,'Enter logical module name ',$) accept 1998,loglen,logmod 1998 format(q,a) if (loglen.le.0) call exit c++ c c Assign a key to the module for keyed reference. c c-- status=cam$assign(logmod(1:loglen),key) if (.not.status) then call lib$stop(%val(status)) end if c++ c c LAM wait service loop. c c-- 2001 continue c++ c c Wait for a LAM from the specified CAMAC module. c The maximum amount of time to wait is specified by c the time out variable(TIME_OUT) in units of seconds. c In this case, TIME_OUT is defined as a PARAMETER. c It may also be defined as a variable. c c-- status=cam$lamwait(%descr(key),time_out) c++ c c This represents the proper method for checking for c success or failure status from the CAM$LAMWAIT procedure c call. The status returned from the procedure call indicates c (1) the LAM occurred within the specified amount of time, c indicated by a 'SS$_WASSET' value or (2) the LAM did not c occur within the specified amount of time, indicated by a c 'SS$_WASCLR' value or (3) the LAM wait request was not c executed due to an anomolous condition as indicated by the c return status. c c-- if (.not.status) then call lib$signal(%val(status)) call cam$dassgn(key) go to 1001 end if if (status.eq.%loc(ss$_wasclr)) then type *,logmod,' LAM wait failed' else type *,logmod,' LAM wait successful' end if c++ c LAM SERVICE EXAMPLES Page 6-3 c Repeat LAM wait test? c c-- type 1996 1996 format(1x,'Go again? Y/N[Y] ',$) accept 1998,resplen,response if (resplen.le.0 .or. 9 response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y') go to 2001 call cam$dassgn(key) go to 1001 end 6.2 A LAM AST Example Using Hibernate/Wake Services This program exercises the CAMAC access procedure that sets a LAM AST for a particular CAMAC module. In this case, a Jorway Manual Input Module. With this module a LAM may be asserted for a the station by setting a switch on the module front panel. This example is particularly simple. It uses hibernate and wake system services to synchronize main program execution with LAM AST delivery. program lamtest implicit integer(a-z) c++ c c Note: Procedure names specified as arguments in c procedure calls must be declared as external symbols. c Otherwise, the FORTRAN compiler will mistake the symbol c for a variable name in the calling procedure. C C-- external lamast c++ c c Define a CAMAC I/O status block buffer c c-- integer*4 iosb(2) c++ c c Use CHARACTER variables for logical module names. c c-- character logmod*32,response*4 c++ c c We must enable AST delivery for the process when c using CAM$LAMAST, otherwise, AST delivery will be c blocked. This is a function of the design of VMS. c c-- call sys$setast(%val(1)) c++ c c Prompt the user for the logical module name. LAM SERVICE EXAMPLES Page 6-4 c c-- 1001 continue type 1999 1999 format(1x,'Enter logical module name ',$) accept 1998,loglen,logmod 1998 format(q,a) if (loglen.le.0) call exit c++ c c LAM AST loop. c c-- 2001 continue c++ c c Request a LAM AST for the specified CAMAC module via c the CAM$LAMASTW procedure call. Once the LAM AST has been c enabled for the specified module, control returns to the c calling program and normal execution may continue. When c the LAM from the module is recognized by the system, the c normal execution of the program is suspended and the LAM AST c procedure is called(i.e. the normal execution is interrupted c to service the LAM). c c c-- status=cam$lamastw(logmod(1:loglen),lamast,%val(lam_efn),iosb) c++ c c This represents the standard error checking procedure that c should be incorporated following a request to set a LAM AST. c Note that the IOSB returned from this call is not guaranteed c to look like a standard CAMAC I/O status block resulting from c one of the CAMAC I/O calls. A success status from the CAM$LAMAST c call indicates that the request was queued to the VAX internal CAMAC c software for processing. A success status from the I/O status block c indicates that the LAM AST was actually queued for the specified c module. c c-- if (.not.status) then call lib$signal(%val(status)) call cam$dassgn(key) go to 1001 else if (.not.iosb(1)) then call lib$signal(%val(iosb(1))) call cam$dassgn(key) go to 1001 end if end if c++ c c Request that process hibernate. The LAM AST procedure will post c a wakeup request for the process when the LAM is generated. c LAM SERVICE EXAMPLES Page 6-5 c-- call sys$hiber c++ c c Repeat LAM test again? c c-- type 1996 1996 format(1x,'LAM delivered successfully'/ 9 1x,'Go again? Y/N[Y] ',$) accept 1998,resplen,response if (resplen.eq.0 .or. 9 response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y') go to 2001 go to 1001 end integer function lamast(astprm) implicit integer(a-z) c++ c c Simple LAM AST Service Procedure. c c This LAM service procedure posts a wakeup request for c the process in response to the LAM. If the process is c currently hibernating, it will be awakened at the point c where the hibernate request was made. If it is not presently c hibernating, the next hibernate request will be satisfied c immediately. Note that VMS does not maintain a count of c pending wakeup requests for the process, i.e. "wakeup c request pending" is simply a "LOGICAL" variable maintained c by VMS for the process. c c-- status=sys$wake(,) if (.not.status) then call lib$stop(%val(status)) end if return end 6.3 A LAM AST Example Using Process Local Event Flags This program exercises the CAMAC access procedure that sets a LAM AST for a particular CAMAC module. In this case, a Jorway Manual Input Module. With this module a LAM may be asserted for a the station by setting a switch on the module front panel. The program utilizes process local event flags to synchronize the LAM AST procedure with the execution of the main procedure. This use of local event flag system services represents one common method for synchronization of AST's with the normal execution of a program. program lamtest implicit integer(a-z) parameter lam_efn=32 ! lam ast synchronization event flag c++ c LAM SERVICE EXAMPLES Page 6-6 c Note: Procedure names specified as arguments in c procedure calls must be declared as external symbols. c Otherwise, the FORTRAN compiler will mistake the symbol c for a variable name in the calling procedure. C C-- external lamast c++ c c Use a common block for communication between the AST procedure c and the main program. This is a common technique for sharing c data between the main program flow and AST procedures. c c-- common/astblk/ ast_parm c++ c c Define a CAMAC I/O status block buffer c c-- integer*4 iosb(2) c++ c c Use CHARACTER variables for logical module names. c c-- character logmod*32,response*4 c++ c c We must enable AST delivery for the process when c using CAM$LAMAST, otherwise, AST delivery will be c blocked. This is a function of the design of VMS. c c-- call sys$setast(%val(1)) c++ c c Prompt the user for the logical module name. c c-- 1001 continue type 1999 1999 format(1x,'Enter logical module name ',$) accept 1998,loglen,logmod 1998 format(q,a) if (loglen.le.0) call exit c++ c c Assign a key to the logical module for keyed reference. c c-- status=cam$assign(logmod(1:loglen),key) if (.not.status) then call lib$stop(%val(status)) end if c++ c LAM SERVICE EXAMPLES Page 6-7 c LAM AST loop. c c-- 2001 continue c++ c c Clear process local event flag before LAM AST call. c c-- call sys$clref(%val(lam_efn)) c++ c c Request a LAM AST for the specified CAMAC module via c the CAM$LAMASTW procedure call. Once the LAM AST has been c enabled for the specified module, control returns to the c calling program and normal execution may continue. When c the LAM from the module is recognized by the system, the c normal execution of the program is suspended and the LAM AST c procedure is called(i.e. the normal execution is interrupted c to service the LAM). c c c-- status=cam$lamastw(%descr(key),lamast,%val(lam_efn),iosb) c++ c c This represents the standard error checking procedure that c should be incorporated following a request to set a LAM AST. c Note that the IOSB returned from this call is not guaranteed c to look like a standard CAMAC I/O status block resulting from c one of the CAMAC I/O calls. A success status from the CAM$LAMAST c call indicates that the request was queued to the VAX internal CAMAC c software for processing. A success status from the I/O status block c indicates that the LAM AST was actually queued for the specified c module. c c-- if (.not.status) then call lib$signal(%val(status)) call cam$dassgn(key) go to 1001 else if (.not.iosb(1)) then call lib$signal(%val(iosb(1))) call cam$dassgn(key) go to 1001 end if end if c++ c c Wait for process local event flag to be posted. c c-- call sys$waitfr(%val(lam_efn)) c++ c c This check isn't really necessary. It is primarily LAM SERVICE EXAMPLES Page 6-8 c included as a demonstration of a method for communicating c information between an AST and the main program flow. c c-- if (lam_efn.ne.ast_parm) then type 1997,lam_efn,ast_parm else type *,'lam delivered successfully' end if 1997 format(1x,'Lam_EFN=',z8,' AST_Parm=',z8) c++ c c Repeat LAM test again? c c-- type 1996 1996 format(1x,'Go again? Y/N[Y] ',$) accept 1998,resplen,response if (resplen.eq.0 .or. 9 response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y') go to 2001 call cam$dassgn(key) go to 1001 end integer function lamast(astprm) implicit integer(a-z) c++ c c Simple LAM AST Service Procedure. c c This LAM service procedure copies the AST parameter c to the COMMON blockand then posts a process local c event flag. The event flag value is assumed to be the c AST parameter specified when the LAM AST request was c made. c c-- common /astblk/ ast_parm ast_parm=%loc(astprm) call sys$setef(%val(ast_parm)) return end CHAPTER 7 CAMAC COMMAND LIST EXAMPLES The discussion of CAMAC command lists in chapter 2 attempts to lay the conceptual framework for the manner in which such command lists are generated and executed. This chapter deals with the specific procedure calls available for utilizing the command list capabilities of the VAX CAMAC system. It is assumed that the reader has completed chapter 2 at this point and has some understanding of the concepts discussed therein relative to command lists. 7.1 A List Mode Example For The LRS 2551 Multi-channel Scaler This program demonstrates the way in which a command list can be used to interact with a Le Croy Systems 2551 Multi-channel Scaler module. The program uses the CAM$DCLST, CAM$LPIO, CAM$LQSCAN and CAM$EXECUTE list mode procedure calls. Basicallly, the program initializes the LRS 2551 module, generates a CAMAC command list and then enters a test loop to repetatively execute the list and verify the results. program l2551 implicit integer(a-z) c++ c c Define buffer parameters c c-- parameter l2551_nchan=12 ! number of LRS 2551 channels c++ c c Execute list and reply list buffer parameters c c-- parameter exe_datal=0 ! execute list data length parameter exe_hdrlen=10 ! execute list header length parameter exe_maxcmd=2 ! max command frame count parameter exe_length=exe_hdrlen+ 9 exe_maxcmd*3+ 9 exe_datal ! execute list length(i*2 count) parameter rep_length=l2551_nchan*2 ! reply list length(i*2 count) parameter mem_l=24 ! memory format=24 bit c++ c CAMAC COMMAND LIST EXAMPLES Page 7-2 c Define execute list buffer and reply list buffers c c-- integer*2 exe_list(0:exe_length), 9 rep_list(0:rep_length) c++ c c Use CHARACTER variables for logical module names. c c-- character*32 logmod c++ c c Misc declarations c c-- logical*4 cam$go type *,'LRS 2551 Module Exercisor' c++ c c Prompt user for logical module name. c c-- type 1999 1999 format(1x,'Enter logical module name ',$) accept 1998,loglen,logmod 1998 format(q,a) if (loglen.eq.0) call exit c++ c c Initialize counter and then initialize c the LRS 2551 scaler module. c c-- countl=0 tc=12 a=0 f=9 status=cam$pio(logmod(1:loglen),a,f) if (.not.cam$go(status,)) call exit c++ c c Declare execute list buffer. c Note that the memory format(defined as a parameter) is explicitly c specified to override the CAMAC image block default value. c c-- status=cam$dclst(exe_list,exe_length,mem_l) if (.not.status) then call lib$stop(%val(status)) end if c++ c c*** Frame 1 c c Generate command frame to perform the channel increment c operation for the LRS 2551 module. CAMAC COMMAND LIST EXAMPLES Page 7-3 c c-- f=25 status=cam$lpio(exe_list,logmod(1:loglen),a,f) if (.not.status) then call lib$stop(%val(status)) end if c++ c c*** Frame 2 c Generate command frame to perform Q-Scan operation fo read c all 12 channels from the LRS 2551 module. c c-- f=0 status=cam$lqscan(exe_list,logmod(1:loglen),a,f,l2551_nchan) if (.not.status) then call lib$stop(%val(status)) end if c++ c c LRS 2551 test loop. c c-- 1001 continue status=cam$executew(exe_list,rep_list,rep_length) if (.not.cam$go(status,)) then call exit end if countl=countl+1 call verify(countl,rep_list,l2551_nchan) go to 1001 end logical function cam$go(status,iosb) implicit integer(a-z) integer*4 iosb(*),liosb(2) logical*4 cam$error character response*4 c++ c c Assume failure by setting 'GO' false. c c-- cam$go=.false. c++ c c Test return status from CAMAC call. If failure indicated, c signal condition and prompt for action if control returns c after signal. c c-- if (.not.status) then call lib$signal(%val(status)) go to 1001 end if c++ c CAMAC COMMAND LIST EXAMPLES Page 7-4 c If IOSB parameter specified as null, then sample the CAMAC c image block IOSB. c-- if (%loc(iosb).eq.0) then call cam$get_stat(liosb) else liosb(1)=iosb(1) liosb(2)=iosb(2) end if c++ c c Test for any CAMAC errors. If so, then display nature of c the CAMAC error via CAM$SHOW_STAT and prompt for action. c c-- if (cam$error(.true.,,liosb)) then call cam$show_stat(liosb) go to 1001 end if c++ c c Change assumed failure to success and return. c c-- cam$go=.true. return c++ c c Prompt for failure override response. c c-- 1001 continue type 1999 1999 format(1x,'Override Failure? Y/[N] ',$) accept 1998,resp_len,response 1998 format(q,a) if (resp_len.eq.1 .and. 9 (response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y')) cam$go=.true. return end subroutine verify(countl,datal,nchan) implicit integer(a-z) integer*4 datal(*) c++ c c Verify that all channels read from the LRS 2551 match c the expected count value(countl). Display channels that c do not match. c c-- do i=1,nchan if (countl.ne.datal(i)) then type 1999,i,countl,datal(i) end if 1999 format(1x,'Mismatch: Chan=',i,2x,i,' Expected; ',i,' Read') end do CAMAC COMMAND LIST EXAMPLES Page 7-5 return end 7.2 A List Mode Example For The LRS 8801 Memory Module This program is designed to demonstrate the use of the VAX CAMAC system list mode access procedures. The program uses a Le Croy Systems 8801/16 memory module to exercise the CAM$DCLST, CAM$LPIO, CAM$LSTOP and CAM$EXECUTEW CAMAC library procedures. The program also uses the CAM$ASSIGN and CAM$PIOW procedures. The program initializes the LRS 8801 module, builds a CAMAC command list, then enters a test loop to repetitively execute the command list, updating the CAMAC write data in the execute list buffer and extracting CAMAC read data from the reply list buffer on each repetition of the test loop. program l8801m4 implicit integer(a-z) parameter maxb=4096 ! max xfer size(bytes) parameter max16=maxb/2 ! max xfer size(i*2) parameter max24=maxb/4 ! max xfer size(i*4) c++ c c Execute and reply list parameters c To aviod confusion and possible programming errors, c execute list and reply list buffers should be declared c as INTEGER*2 arrays. The length parameters defined below c are generated to adhere to this convention. There is no c real restriction on type for execute list or reply list c bufffers, however. c c-- parameter exe_hdrlen=10 ! exe list hdr len(i*2 count) parameter exe_maxcmd=10 ! max command frame count parameter exe_datal=maxb/2+8 ! exe list data(i*2 count) parameter exe_length=exe_hdrlen+ 9 exe_maxcmd*3+ 9 exe_datal ! exe list length(i*2 count) parameter rep_length=maxb/2+8 ! rep list length(i*2) parameter mem_w=16 ! 16 bit memory format c++ c c Execute and reply list declarations c Note: The execute list and reply list buffers are declared c as zero relative arrays to allow the direct use of FIB pointers c (if so desired) without offseting by 1 to compensate for the c indexing convention utilized by the CAMAC access software. c c-- integer*2 exe_list(0:exe_length),rep_List(0:rep_length) c++ c c Frame Information Block(FIB) parameters c c-- parameter fib_length=4 ! FIB struc length(i*2) parameter fib_w_cndx=1 ! FIB command index offset CAMAC COMMAND LIST EXAMPLES Page 7-6 parameter fib_b_fcode=2 ! FIB fcode offset parameter fib_w_dndx=3 ! FIB data index offset parameter fib_w_dsiz=4 ! FIB data size offset c++ c c FIB List(FIBL) for the execute list. c c FIB list entries are indexed by the command frame number. c The symbolic offsets(defined as parameters) are used to c reference the fields of the FIB data structure for a given c command frame. c c-- integer*2 fib_list(fib_length,exe_maxcmd) c++ c c Define program local CAMAC I/O status block c c-- integer*4 iosb(2) c++ c c Working data buffers to use for manipulating CAMAC read c and write data vs. actually referencing the data in the c reply and execute list buffers. c c-- integer*2 caminp(max16),camout(max16) c++ c c Use CHARACTER variables for logical module names. c c-- character*32 logmod c++ c c Misc. declarations c c-- logical*4 cam$go data map/0/ c++ c c Prompt user for logical module name. c c-- type 1999 1999 format(1x,'Enter lrs 8801 module ',$) accept 1998,loglen,logmod 1998 format(q,a) if (loglen.eq.0) call exit c++ c c Assign key to the LRS 8801 module. c c-- status=cam$assign(logmod,keyv) CAMAC COMMAND LIST EXAMPLES Page 7-7 if (.not.status) then call lib$stop(%val(status)) end if c++ c c Prompt user for desired transfer count. c c-- 3001 continue type 1995,max16 1995 format(1x,'Enter transfer count;',i,' limit ',$) accept *,tc if (tc.le.0 .or. tc.gt.max16) then type 1993,tc go to 3001 end if 1993 format(1x,'Invalid transfer count=',i) c++ c c Initialize the LRS 8801 module using non-list c mode CAMAC access calls. c Perform a module clear(A0,F9), c Disable the external memory port(A0,F19), c Enable auto-increment mode for the MAP(A0,F25). c c-- a=0 f=9 status=cam$piow(%descr(keyv),a,f,,,iosb) if (.not.cam$go(status,iosb)) call exit f=19 status=cam$piow(%descr(keyv),a,f,0,16,iosb) if (.not.cam$go(status,iosb)) call exit f=25 status=cam$piow(%descr(keyv),a,f,,,iosb) if (.not.cam$go(status,iosb)) call exit c++ c c Initialize the execute list buffer c This call sets up the execute list header(actually c part of the execute list itself) and readies it to c receive command and data frames generated by CAMAC c command list calls. Things to note include: c 1. The execute list buffer length is specified c in I*2 units(i.e. words). c 2. The memory format(defined as a parameter in c this case) applies to all CAMAC operations c from the list, both read and write. c 3. A FIBL is attached for this execute list buffer. c c-- call cam$dclst(exe_list,exe_length,mem_w,fib_list) c++ c c*** Frame 1 c Generate a list programmed I/O command and data frames c to reset the LRS 8801 MAP. The value in the variable CAMAC COMMAND LIST EXAMPLES Page 7-8 c MAP is copied into the data frame for the programmed c I/O operation. c c-- f=18 status=cam$lpio(exe_list,%descr(keyv),a,f,map) if (.not.status) then call lib$stop(%val(status)) end if c++ c c*** Frame 2 c Generate a list Stop mode command frame to write the c a data frame to the LRS 8801 module. No data is actually c copied to the data frame in this case, however. Space c is reserved in the execute list buffer for the specified c amount of data. The transfer count(TC) is in units of the c memory format associated with the execute list buffer. c c-- f=16 status=cam$lstop(exe_list,%descr(keyv),a,f,tc) if (.not.status) then call lib$stop(%val(status)) end if c++ c c*** Frame 3 c Generate list PIO command frame and data frame to write the c LRS 8801 MAP register in preparation for reading back the c data buffer previously written to the module. c c-- f=18 status=cam$lpio(exe_list,%descr(keyv),a,f,map) if (.not.status) then call lib$stop(%val(status)) end if c++ c c*** Frame 4 c Generate a list PIO command frame to perform a read c operation to the LRS 8801 module to prime the module for c a block transfer. Otherwise, the first two words returned c from the module in the block transfer will be the same. c c-- f=2 status=cam$lpio(exe_list,%descr(keyv),a,f) if (.not.status) then call lib$stop(%val(status)) end if c++ c c*** Frame 5 c Generate a list Stop mode command frame to read the data c written to the LRS 8801 module. CAMAC COMMAND LIST EXAMPLES Page 7-9 c c-- status=cam$lstop(exe_list,%descr(keyv),a,f,tc) if (.not.status) then call lib$stop(%val(status)) end if c++ c c LRS 8801 test loop c c-- 4001 continue c++ c c Generate data pattern to write to LRS 8801 c c-- call gen16(camout,tc) c c Update data for frame 2 of execute list c c-- call cam$wdata(exe_list,2,camout) c++ c c Execute command list c c-- status=cam$executew(exe_list,rep_list,rep_length,iosb) if (.not.cam$go(status,iosb)) call exit c++ c c Retrieve read data for frame 5 from reply list c c-- call cam$rdata(exe_list,5,rep_list,caminp) c++ c c Verify CAMAC data read from LRS 8801 with data written to c LRS 8801. c c-- call verify(camout,caminp,tc) go to 4001 end logical function cam$go(status,iosb) implicit integer(a-z) integer*4 iosb(*),liosb(2) logical*4 cam$error character response*4 c++ c c Assume failure. c c-- cam$go=.false. c++ CAMAC COMMAND LIST EXAMPLES Page 7-10 c c Determine if system error occurred. If so, signal c the error condition and if control returns, go prompt c for desired action. c c-- if (.not.status) then call lib$signal(%val(status)) go to 1001 end if c++ c c If the IOSB is specified as null, sample the CAMAC image block c IOSB value, else, use the specified IOSB buffer. c c-- if (%loc(iosb).eq.0) then call cam$get_stat(liosb) else liosb(1)=iosb(1) liosb(2)=iosb(2) end if c++ c c Determine if a CAMAC error occurred. If so, display c the CAMAC I/O status block contents and then go prompt c for desired action. c c-- if (cam$error(,,liosb)) then call cam$show_stat(liosb) go to 1001 end if c++ c c Change assumed failure to success and return. c c-- cam$go=.true. return c++ c c Manual override of failure status? c c-- 1001 continue type 1999 1999 format(1x,'Override failure? Y/N[N] ',$) accept 1998,resp_len,response 1998 format(q,a) if (resp_len.eq.1 .and. 9 (response(1:1).eq.'y' .or. 9 response(1:1).eq.'Y')) cam$go=.true. return end subroutine gen16(camout,tc) implicit integer(a-z) CAMAC COMMAND LIST EXAMPLES Page 7-11 integer*2 camout(1) integer*2 tpat16/'3333'x/ c++ c c Generate a test pattern into the specified INTEGER*2 c buffer according to the length specified by the transfer c count variable(TC). The test pattern is replaced by it's c ones complement after the buffer is loaded. c c-- do tndx=1,tc camout(tndx)=tpat16 end do tpat16=-tpat16-1 return end subroutine verify(outdat,inpdat,wc) implicit integer(a-z) integer*2 outdat(*),inpdat(*) c++ c c Verify each INTEGER*2 element of the specified output c data buffer aganist each element of the specified INTEGER*2 c input data buffer according to the length specified by the c word count variable(WC). The verification terminates at the c first data mismatch. c c-- do ndx=1,wc if (inpdat(ndx).ne.outdat(ndx)) then type 1999,ndx,outdat(ndx),inpdat(ndx) return end if end do 1999 format(1x,'Pos=',i,' Output=',z4,' Input=',z4) return end APPENDIX A CAMAC ACCESS PROCEDURE SUMMARY A.1 Basic CAMAC Access Procedures 1. Programmed I/O -This call performs a single-action CAMAC transaction. CAM$PIO(W)(MODULE,A,F[,DATA][,MEM][,IOSB][,EFN][,AST][,ASTP]) CAM$PIO(W)(%DESCR(KEY),A,F,[,DATA][,MEM][,IOSB][,EFN][,AST][,ASTP]) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. DATA is an I*2, I*4 variable containing/to receive CAMAC data. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when CAMAC ACCESS PROCEDURE SUMMARY Page A-2 called. 2. Q-Scan/Stop On Word Count Transaction -This call performs a CAMAC Q-Scan transaction. The transaction terminates when (1) the specified number of transfers have been completed, (2) when the CAMAC station number increments out of legal range or (3) an anomolous transmission condition is detected by the highway driver hardware. CAM$QSCAN(W)(MODULE,A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) CAM$QSCAN(W)(%DESCR(KEY),A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. TC is an I*2, I*4 variable containing the transfer count. DATA is a BYTE, I*2, I*4 array containing/to receive CAMAC data. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when called. 3. Q-Stop/Stop On Word Count Transaction -This call performs a CAMAC Q-Stop transaction. The transaction terminates when (1) the specified number of transfers have been completed, (2) a Q response of 0 is received on a CAMAC cycle or (3) an anomolous transmission condition is detected by the highway driver hardware. CAMAC ACCESS PROCEDURE SUMMARY Page A-3 CAM$QSTOP(W)(MODULE,A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) CAM$QSTOP(W)(%DESCR(KEY),A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. TC is an I*2, I*4 variable containing the transfer count. DATA is a BYTE, I*2, I*4 array containing/to receive CAMAC data. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when called. 4. Stop On Word Count Transaction -This call performs a CAMAC Stop mode transaction. The transaction terminates when (1) the specified number of transfers have been completed or (2) an anomolous transmission condition is detected by the highway driver hardware. CAM$STOP(W)(MODULE,A,F,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) CAM$STOP(W)(%DESCR(KEY),A,F,,TC,DATA[,MEM][,IOSB][,EFN][,AST][,ASTP]) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced CAMAC ACCESS PROCEDURE SUMMARY Page A-4 KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. TC is an I*2, I*4 variable containing the transfer count. DATA is a BYTE, I*2, I*4 array containing/to receive CAMAC data. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when called. 5. Assign key to a logical CAMAC module -This call assigns an encoded key value to a logical CAMAC module which may subsequently be used to expedite references to the module in CAMAC I/O calls. CAM$ASSIGN(MODULE,KEY) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. 6. Release a logical module key -This procedure call releases a CAMAC module key previously assigned via the CAM$ASSIGN procedure call. CAM$DASSGN(KEY) where CAMAC ACCESS PROCEDURE SUMMARY Page A-5 KEY is an I*4 variable containing a key value previously assigned via CAM$ASSIGN. 7. Alter CAMAC Image Block state values -This procedure call allows the user to alter the default CAMAC state variables in the CIB. The CIB values that are directly controllable appear as arguments in the procedure call. Arguments that are omitted in the call(i.e. specified as null arguments) are mod altered. CAM$CSTATE(EFN,XSTATE,QSTATE,MEM) where EFN is the value of the process local event flag to be used for I/O synchronization. XSTATE is a BYTE, I*2, I*4 variable containing one of the symbolic values CAM$_XI, CAM$_XE. This state variable controls highway driver hardware error logic for whether the X response is ignored or considered, respectively, for programmed I/O and list programmed I/O operations. QSTATE is a BYTE, I*2, I*4 variable containing one of the symbolic values CAM$_QDC, CAM$_QNE, CAM$_QE. This state variable controls highway driver hardware error logic for whether the Q response is considered and if so, the expected Q response(0 or 1), respectively, for programmed I/O and list programmed I/O operations. MEM is a BYTE, I*2, I*4 variable containing a value of 16 or 24 to indicate the default memory format value. A.2 CAMAC Command List Procedures 1. Declare and initialize execute list buffer -This procedure takes the specified user buffer and initializes it to serve as a CAMAC command list buffer. CAM$DCLST(EXE_LST,EXE_LEN,MEM,FIBL) where EXE_LST is an I*2 array to be used as an execute list buffer. EXE_LEN is the length of the execute list buffer in units of I*2 elements. CAMAC ACCESS PROCEDURE SUMMARY Page A-6 MEM is a BYTE, I*2, I*4 variable containing a value of 24 or 16 to specify the execute list memory format. FIBL is an I*2, 4 X NN array to be used as a Frame Information Block(FIB) list for the execute list. The FIB is required to reference data by frame number. The rule for determining the size of the execute list buffer is as follows: EXE_LEN = EXE_HDRLEN + EXE_MAXCMD*3 + EXE_DATAL where EXE_HDRLEN = Execute list header size(in I*2 elements; Value=10) EXE_MAXCMD = Maximum number of list command frames. EXE_DATAL = Maximum number of I*2 elements required for CAMAC write data. 2. Generate List Programmed I/O Command Frame -This procedure call generates a programmed I/O command frame into the specified execute list. Optionally, the procedure may alter the module parameters, subaddress, function code and/or data for an existing command frame if the frame number is specified and the execute list has a FIBL attached. CAM$LPIO(EXE_LST,MODULE,A,F[,DATA][,FRAME]) CAM$LPIO(EXE_LST,%DESCR(KEY),A,F[,DATA][,FRAME]) where EXE_LST is an I*2 array previously declared as an execute list buffer via the CAM$DCLST call. MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. DATA is a BYTE, I*2, I*4 variable containing CAMAC write data to be copied into the execute list as the data frame for the write command frame. If the function code performs a read or control operation or if the data frame is to be inserted dynamically(eg. via CAM$WDATA), this CAMAC ACCESS PROCEDURE SUMMARY Page A-7 argument may be omitted. FRAME is an I*2, I*4 variable containing a frame number corresponding to an existing command frame in the execute list buffer. If specified, the corresponding frame in the execute list buffer is modified with the module data, subaddress, function code and write data as specified in the call. Note that this random list update is not allowed if the resulting comand frame or data frame is different in length from the existing command or data frames nor is it allowed if the function code is not of the same class(read, write, control) as the existing frame. 3. Generate List Q-Scan Command Frame -This procedure call generates a command frame in the specified execute list buffer to perform a CAMAC Q-Scan transaction. Optionally, the procedure may alter the module data, subaddress, function code and/or data for an existing command frame if the frame number is specified and the execute list has a FIBL attached. CAM$LQSCAN(EXE_LST,MODULE,A,F,TC[,DATA][,FRAME]) CAM$LQSCAN(%DESCR(KEY),A,F,TC[,DATA][,FRAME]) where EXE_LST is an I*2 array previously declared as an execute list buffer via the CAM$DCLST call. MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. TC is an I*2, I*4 variable containing the transfer count. DATA is a BYTE, I*2, I*4 array containing CAMAC write data to be copied into the execute list as the data frame for the write command frame. If the function code performs a read operation or if the data frame is to be inserted dynamically(eg. via CAM$WDATA), this argument may be omitted. FRAME is an I*2, I*4 variable containing a frame number corresponding to an existing command frame in the execute list buffer. If specified, the corresponding frame in the execute list buffer is modified with the module data, subaddress, function code and write data as specified in the call. Note that this random list update is not allowed if the resulting comand frame or data frame is different in length from the existing command or data frames nor is it allowed if the function code CAMAC ACCESS PROCEDURE SUMMARY Page A-8 is not of the same class(read, write, control) as the existing frame. 4. Generate List Stop Mode Command Frame -This procedure call will generate a Stop mode command frame in the specified execute list buffer. Optionally, the procedure may alter the module data, subaddress, function code and/or data for an existing command frame if the frame number is specified and the execute list has a FIBL attached. CAM$LSTOP(EXE_LST,MODULE,A,F,TC[,DATA][,FRAME]) CAM$LSTOP(EXE_LST,%DESCR(KEY),A,F,TC[,DATA][,FRAME]) where EXE_LST is an I*2 array previously declared as an execute list buffer via the CAM$DCLST call. MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. A is a BYTE,I*2,I*4 variable containing the CAMAC subaddress. F is a BYTE, I*2, I*4 variable containing the CAMAC function code. TC is an I*2, I*4 variable containing the transfer count. DATA is a BYTE, I*2, I*4 array containing CAMAC write data to be copied into the execute list as the data frame for the write command frame. If the function code performs a read operation or if the data frame is to be inserted dynamically(eg. via CAM$WDATA), this argument may be omitted. FRAME is an I*2, I*4 variable containing a frame number corresponding to an existing command frame in the execute list buffer. If specified, the corresponding frame in the execute list buffer is modified with the module data, subaddress, function code and write data as specified in the call. Note that this random list update is not allowed if the resulting comand frame or data frame is different in length from the existing command or data frames nor is it allowed if the function code is not of the same class(read, write, control) as the existing frame. 5. Execute CAMAC Command List -This procedure call will execute the specified execute list buffer, depositing CAMAC read data into a specified reply list buffer. CAM$EXECUTE(W)(EXE_LST[,REP_LST,REP_LEN][,IOSB][,EFN][,AST][,ASTP]) CAMAC ACCESS PROCEDURE SUMMARY Page A-9 where EXE_LST is an execute list buffer assumed to have been previously initialized via CAM$DCLST and containing valid CAMAC command frames generated by the list mode access procedures CAM$LPIO, CAM$LQSCAN or CAM$LSTOP. REP_LST is an I*2 array to receive the CAMAC read data resulting from the execution of the specified execute list buffer. If the given execute list performs no read operations, the reply list may be omitted. REP_LEN is an I*2, I*4 variable containing the length of the reply list buffer in uints of I*2 elements. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when called. A.3 CAMAC Status Procedures Test CAMAC IOSB For Error -This procedure examines the CAMAC I/O status block for universal failure indicators. In addition, arguments may be specified to indicate the expected state of the CAMAC X and Q responses as well. The procedure returns a .TRUE. function value if an anomolous condition is detected, .FALSE. otherwise. CAM$ERROR([EXP_X][,EXP_Q][,IOSB]) where EXP_X is a LOGICAL variable(*1, *2, *4) indicating the expected state of the CAMAC X response. If specified as a null argument(i.e. ,,) the X response is not examined. EXP_Q is a LOGICAL variable(*1, *2, *4) indicating the expected state of the CAMAC Q response. If specified as a null argument(i.e. ,,) the CAMAC ACCESS PROCEDURE SUMMARY Page A-10 Q response is not examined. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. 1. Test CAMAC IOSB For X Response _This procedure examines the CAMAC IOSB for the X response and returns a .TRUE. value if X=1, .FALSE. otherwise. CAM$X([IOSB]) where IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as a null argument, the IOSB from the CIB is used. 2. Test CAMAC IOSB For Q Response -This procedure examines the CAMAC I/O status block for the Q response and returns a .TRUE. value if Q=1, .FALSE. otherwise. CAM$Q([IOSB]) where IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as a null argument, the IOSB from the CIB is used. 3. Test CAMAC IOSB For X and Q Response -This procedure examines the CAMAC I/O status block for both X and Q responses and returns a .TRUE. value if (X=1 .AND. Q=1), .FALSE. otherwise. CAM$XANDQ([IOSB]) where IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as a null argument, the IOSB from the CIB is used. 4. Sample CAMAC Image Block(CIB) IOSB -This procedure samples the CIB IOSB and returns it's current state to CAMAC ACCESS PROCEDURE SUMMARY Page A-11 the specified quadword user buffer. CAM$GET_STAT(IOSB) where IOSB is a quadword buffer to receive the CIB IOSB contents. 5. Summarize and Display CAMAC IOSB Contents -This procedure call decodes the CAMAC IOSB and displays a summary of it's contents to the VAX logical output device SYS$OUTPUT. CAM$SHOW_STAT([IOSB]) where IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as a null argument, the IOSB from the CIB is used. A.4 CAMAC LAM Service Procedures 1. Set LAM AST For A CAMAC Module _This procedure call associates a LAM AST with a specified CAMAC module. When the LAM is recognized by the CAMAC system, the AST service procedure is called, interrupting normal program execution to service the LAM. CAM$LAMAST(MODULE,LAM_AST,LAM_ASTP[,IOSB][,EFN][,AST][,ASTP]) CAM$LAMAST(%DESCR(KEY),LAM_AST,LAM_ASTP[,IOSB][,EFN][,AST][,ASTP]) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. LAM_AST is a VAX procedure name(FUNCTION or SUBROUTINE) to be called CAMAC ACCESS PROCEDURE SUMMARY Page A-12 when the LAM AST is delivered to the process. LAM_ASTP is an I*4 value to be passed to the LAM AST service procedure. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when called. 2. Cancel Previous LAM AST Request -This procedure cancels a previously requested LAM AST from a particular CAMAC module. CAM$CANLAM(MODULE,[,IOSB][,EFN][,AST][,ASTP]) CAM$CANLAM(%DESCR(KEY)[,IOSB][,EFN][,AST][,ASTP]) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. IOSB is a quadword buffer assumed to contain valid CAMAC I/O status. If not specified or specified as null, the IOSB from the CIB is used. MEM is a BYTE, I*2, I*4 variable containing 16 or 24 for memory format control. EFN is the value of a process local event flag used for I/O synchrnoization. AST is the name of a VAX procedure(FUNCTION or SUBROUTINE) to service the I/O completion AST. ASTP is an I*4 value to be passed to the AST service procedure when called. CAMAC ACCESS PROCEDURE SUMMARY Page A-13 3. CAM$LAMWAIT(MODULE,TIME_OUT) CAM$LAMWAIT(%DESCR(KEY),TIME_OUT) where MODULE is a CHARACTER variable containing the ASCII logical module name for the CAMAC module to be referenced KEY is an I*4 variable containing the module key assigned via CAM$ASSIGN. TIME_OUT is an I*2, I*4 variable containing the maximum time to wait (in seconds) before resuming execution. APPENDIX B CAMAC IMAGE BLOCK DEFAULT VALUES Initial values for the controllable "state variables" in the CAMAC Image Block (CIB) data structure are as follows: 1. EFN = %VAL(0) ! DEFAULT EVENT FLAG INITIALLY 0 2. XSTATE = %LOC(CAM$_XI) ! X STATE CONTROL = "X DON'T CARE" 3. QSTATE = %LOC(CAM$_QDC) ! Q STATE CONTROL = "Q DON'T CARE" 4. MEM = 24 ! MEM STATE = "24-BIT" FORMAT