[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

OpenVMS Record Management Services Reference Manual


Previous Contents Index

B.1.2 Applicable VAX MACRO Syntax Rules

One of the conventions used with RMS control block macros is to identify a field by a mnemonic; for example, you can specify the FAB$L_ALQ field using its mnemonic, ALQ. Using a mnemonic ensures the accuracy of argument value placement regardless of how you code the related argument. For example, the mnemonic for the FAB field that specifies the allocation quantity is ALQ. Thus, when using the $FAB macro to initialize the allocation quantity field, you might use the following macro expression:


INFAB:  $FAB  ALQ=500

This macro statement defines the start of the FAB at label (symbolic address) INFAB and initializes the allocation field to provide 500 blocks of space to the specified file.

In this instance, if you want to change the allocation value to 250 blocks at run time, you could use the following macro expression:


MOVL   #250, INFAB+FAB$L_ALQ    ; Set allocation quantity

In fields that contain binary options or keyword values, you should use the appropriate keyword or symbolic binary option value. For example, the FAB uses the ORG field to specify a file organization. Three keywords are defined for this field: SEQ (sequential file), REL (relative file), and IDX (indexed file). To specify an indexed file organization, you should use the following macro expression:


OUTFAB: $FAB  ORG=IDX

To specify an indexed file organization at run time, you must move the value into the field using appropriate symbols:


MOVAL OUTFAB, R5                    ; Move address into R5
MOVB  #FAB$C_IDX, FAB$B_ORG(R5)     ; Store constant value

In control block macros, arguments for bit fields that can contain multiple values are usually enclosed within angle brackets <value_1,value_2,value_n>. Consider the file access (FAC) field (FAB$B_FAC) in the FAB, a bit field that can contain multiple values. To permit a process to do Get and Put operations, the following macro expression could be used:


INFAB:  $FAB  FAC=<GET,PUT>   ; Specify Put and Get operations

Control block macro arguments that are interpreted as ASCII characters (such as a file specification) must also be enclosed within angle brackets. The use of the left angle (<) and right angle (>) delimiters is noted in the format and argument descriptions of the control block macros in Part 2.

At run time, you could use the following code sequence to make the file accessible to a Get operation:


MOVAL OUTFAB, R6                       ; Move FAB addr into R6
BBS   #FAB$V_GET, FAB$B_FAC(R6), OK    ; Go to OK if GET bit set
BISB  #FAB$M_GET, FAB$B_FAC(R6)        ; Else set GET bit
OK:

When you use RMS macros, follow the coding rules used by the VAX MACRO assembler as described in the following list:

  • Comments must be separated from the rest of the code line by a semicolon (;). For example:


    $FAB   BKS=4              ; Bucket size
    
  • All the arguments for a macro must be coded in a single statement. If the arguments do not fit on a line or if you want to use multiple lines, type the continuation character, a hyphen (-), as the last character on the line; then continue typing arguments on the next line. Comments can follow the hyphen. For example:


    $FAB  FNA=FLNAM,-             ; Filename address
          ALQ=100,-               ; Allocation quantity
          BKS=4                   ; Bucket size
    
  • Arguments and subarguments can be separated from each other by one of the following:
    • A comma, with or without spaces or tabs:


      FNA=FLNAM,ALQ=100
      
    • A space:


      FNA=FLNAM ALQ=100
      
    • Multiple spaces or tabs:


      FNA=FLNAM        ALQ=100
      

    The comma without a space or tab is preferred. All coding examples in this manual use a comma to separate arguments.

B.2 Using the RMS Macros

This section provides examples of how to use the four types of RMS macros.

B.2.1 Control Block Initialization Macros

A major advantage to using the control block initialization macros is that they direct the initialization values to the correct field locations in the control block. Returned status values do not apply here because RMS evaluates this type of macro at assembly time, not at run time.

Control block initialization macros are located at the beginning of their associated control block. The initialization macro should have a related label because the address of the control block is a required argument for most services and for some control block macros. As shown in the following example, the label provides a programming convenience for symbolically addressing the control block:


MYFAB:  $FAB

Arguments usually require an address, such as a symbolic address, or a value. RMS initializes the appropriate field by simply taking the supplied argument and placing it after the appropriate macro data declaration directive, as shown in the following code example:


.ADDRESS address
.BYTE value

Arguments that specify field values must be enclosed within angle brackets under the following conditions:

  • When the argument is a file specification (ASCII character string)
  • When more than one argument is supplied for a binary options field, where each bit option is identified by a 3-letter mnemonic
  • Where otherwise indicated in the format of the macro, such as for UICs and file identifiers in which multiple values separated by commas constitute the argument

Here are several examples:


MYFAB:  $FAB     FAC=<GET, PUT>,-        ; Multioption field
                 FNM=<DEGREE_DAY.DAT>,-  ; File specification
   .
   .
   .
                 NXT=MYXPRO,-            ; XAB address
                 ORG=SEQ                 ; Single-option field
;
MYXPRO: $XABPRO  PRO=<RWED,RWED,R,R>,-   ; File protection
                 UIC=<377,377>           ; UIC

Do not position the macro name in a read-only program section because control block fields may receive values during the execution of a service. For efficiency, align the control blocks on a longword boundary. The initialization macros display an informational message in the listing file if the control block is not longword aligned.

In summary, initialization macros must be placed in a writable data program section in which the data has been aligned on a longword boundary.

B.2.2 Control Block Symbol Definition Macros

A control block symbol definition macro includes the macro name only, has no arguments, and can be placed in any program section. The macro name is made up of the associated initialization macro and the suffix DEF.

RMS does not provide return values for control block symbol definition macros.

B.2.3 Control Block Store Macros

A control block store macro consists of executable run-time code, so it must be placed within an executable code program section. R0 cannot be used to return condition codes because control block store macros may use R0 to move arguments. The only detectable errors are assembly-time errors.

The calling format of each control block store macro resembles the calling format of the corresponding initialization macro except that a control block store macro can take a run-time value as an argument. Run-time values include date and time values, file identifier values, device identifier values, directory identifier values, and record file address values.

The following list describes other differences between the format of a control block store macro and its corresponding control block initialization macro:

  • An argument specifying the address of the control block is required unless the calling program provides the control block address in R0. If this argument is not a register value in the form Rn, RMS loads the control block address into R0.
  • For each argument that requires an address, the store macro uses the VAX MACRO instruction MOVAx (usually MOVAL) to move the address into the appropriate control block field. Thus, VAX MACRO expressions can be used. For instance, you can use a symbolic address to specify the control block address argument directly (for example, FAB=MYFAB, NAM=MYNAM, RAB=MYRAB, or XAB=MYXAB).
    You may also specify a register that contains the address using the form Rn, where n is a decimal number from 0 through 12.
  • For each argument that requires a nonkeyword data value, the store macro uses the VAX MACRO instruction MOVx to move data into the appropriate control block field. Thus, VAX MACRO expressions can be used. Note that a number sign (#) must precede a literal nonkeyword value, except when a literal value is enclosed within left angle (<) and right angle (>) brackets. However, if you specify the address where the argument value resides, a number sign must not precede the symbolic address nor the register expression that contains the address.
  • For binary option or keyword value fields, use the supplied keyword without a number sign and do not use a VAX MACRO expression. Multiple keyword arguments must be enclosed within left angle (<) and right angle (>) brackets.

In some cases, arguments are specified as run-time values using one of the following forms:

  • A VAX MACRO expression
  • The symbolic address of the argument value

Example B-1 illustrates the use of the $XABDAT_STORE macro to set the creation date of the file to the beginning of a fiscal quarter, thereby establishing a valid starting date for the file data.

Example B-1 Use of the$XABDAT and$XABDAT_STORE Macros

.TITLE  CREAT  -  SET CREATION DATE
;       Program that uses XABDAT and XABDAT_STORE
;
        .PSECT LONG  WRT,NOEXE
;
MYFAB: $FAB  ALQ=500,FOP=CBT,FAC=PUT, -
             FNM=<DISK$:[PROGRAM]SAMPLE_FILE.DAT>,-
             ORG=SEQ,RAT=CR,RFM=VAR,SHR=NIL,MRS=52,XAB=MYXDAT
;
MYXDAT: $XABDAT
;
ATIM:   .ASCID  /9-AUG-1994 00:00:00.00/
BTIM:   .BLKQ   1
;
        .PSECT  CODE NOWRT,EXE
        .ENTRY  CREAT, ^M<>
START:  $BINTIM_S TIMBUF=ATIM, TIMADR=BTIM   ; Convert ASCII to binary time
        BLBC    R0,SS_ERR                    ; Branch on error
        $XABDAT_STORE XAB=MYXDAT, CDT=BTIM   ; Move time into XAB$Q_CDT
        $CREATE FAB=MYFAB                    ; Create file; populate
        BLBC    R0,ERROR                     ; file later
CLOSE:  $CLOSE  FAB=MYFAB                    ; Close file
        BRB     FINI                         ; and exit
ERROR:  PUSHL   FAB$L_STV+MYFAB              ; Push FAB STS and
        PUSHL   FAB$L_STS+MYFAB              ; STV on stack
        CALLS   #2, G^LIB$SIGNAL             ; Signal error
        BRB     FINI
SS_ERR: PUSHL   R0                           ; Push R0
        CALLS   #1, G^LIB$SIGNAL             ; Signal error
FINI:   RET
        .END CREAT

This short program creates a file with a creation date of midnight, August 9, 1994. The FAB at symbolic address MYFAB defines a sequential file with variable-length records up to 52 bytes in length and specifies an allocation size of 500 blocks using the contiguous-best-try file processing option. It also specifies the file specification. The .ASCID assembler directive defines the constant date-time character string at symbolic address ATIM.

The SYS$BINTIM system service is invoked to convert the constant ASCII time at symbolic address ATIM to binary format in the quadword at BTIM. The BTIM value is moved into the XAB$Q_CDT field of the XABDAT control block at symbolic address MYXDAT using the following XABDAT_STORE macro:


$XABDAT_STORE XAB=MYXDAT, CDT=BTIM

Because the creation date in field XAB$Q_CDT is input to the Create service ($CREATE macro), the value must be stored before the program invokes the Create service. The file is created, then closed. Note that Create service errors are signaled using the FAB$L_STS and FAB$L_STV fields, not R0.

B.2.4 Service Macros

This section describes the general macro format of record management service macros. Part 3 describes each service in detail, including the calling format.

Note that the general information applicable to invoking record management services in Chapter 2 also applies to programs written in VAX MACRO.

The service macros use two general formats:


label: macro-name

label: macro-name   RAB=rab-address,-
                        ERR=entry,-
                        SUC=entry

The first format takes no arguments. You supply the argument list within your program, and the argument pointer register (AP) is assumed to contain the address of the argument list. An example of this format follows.


ARG_LOC: .BLKL 2
   .
   .
   .
MOVL   #1,ARG_LOC            ; Move number of args to ARG_LOC
MOVAL  INFAB, ARG_LOC+4      ; Move FAB address to ARG_LOC+4
MOVAL  ARG_LOC, AP           ; Move ARG_LOC address to AP
$OPEN                        ; Open file

In this form, the $OPEN macro expands to the following VAX MACRO code:


CALLG  (AP), G^SYS$OPEN

In the second format, you supply arguments that automatically generate an argument list on the stack according to the values you supplied. You specify these arguments using keywords, which can be in any order. You must separate keywords using a comma, a blank space, or tabs. The only argument required when using the second format is the control block address (FAB=fab-address or RAB=rab-address). This argument must be either a general register (R0 through R11) containing the control block address, or a suitable address for a PUSHAL instruction. If you omit this argument, no other arguments are allowed; in other words, you must use the first format.

The ERR=entry and SUC=entry arguments are optional and, if used, provide the addresses of completion routine entry points. Completion routines are always executed as ASTs. RMS places the values you supply in the argument list on the stack during execution of the expanded macro. These values must be addresses that can be used by a PUSHAL instruction.

Here is an example of the second format:


$OPEN FAB=INFAB

This macro line expands to the following VAX MACRO code:


PUSHAL  INFAB
CALLS   #01, G^SYS$OPEN

When the argument list contains a completion routine argument, an AST is queued. When the AST routine executes, the following conditions hold:

  • General registers R0 through R11 are undefined. The AP contains the address of the AST argument list; the AST argument value in the AST argument list specifies the address of the associated control block (FAB or RAB). The status must be retrieved from the completion status code field (STS) of the associated control block.
  • Any general registers saved by an entry mask can be modified, in addition to R0 and R1.
  • Additional calls to record management services can be made within the completion routines.
  • To exit from a completion routine, you must perform any necessary cleanup operations and execute a RET instruction.

The calling format of each service is listed alphabetically in Part 3. The format for the Close service is shown in the following code example:


SYS$CLOSE   fab  [,[err]  [,suc]]

When you use a macro to call a service, remember to omit the SYS prefix. For example, use $CLOSE instead of SYS$CLOSE.

All file-processing macros require the FAB address as an argument and optionally allow you to specify the entry points for error or success condition handlers, as shown in the following format illustration:


$macro  FAB=fab-addr  [,ERR=error-entry]  [,SUC=success-entry]

For example, to invoke the $OPEN macro and pass it the FAB address of INFAB and the error entry point of OPEN_ERR, you could use the following macro:


$OPEN   FAB=INFAB, ERR=OPEN_ERR

Note that the $RENAME macro has a different format, as noted in Table B-3. This file processing macro has the following format:


$RENAME  OLDFAB=old-fab-addr [,ERR=error-entry]
         [,SUC=success-entry] ,NEWFAB=new-fab-addr

The format for record processing macros and block I/O macros requires the RAB address as an argument and optionally allows you to specify the entry points for error or success condition handlers, as shown in the following format illustration:


$macro  RAB=rab-addr  [,ERR=error-entry]  [,SUC=success-entry]

Note that the $WAIT macro has a different format, in that it does not use the error and success arguments:


$WAIT   RAB=rab-addr

Table B-3 lists each service macro according to its macro type.

Table B-3 File, Record, and Block I/O Processing Macros
File
Processing
Record
Processing
Block I/O
$CLOSE $CONNECT $READ
$CREATE $DELETE $SPACE
$DISPLAY $DISCONNECT $WRITE
$ENTER $FIND  
$ERASE $FLUSH  
$EXTEND $FREE  
$NXTVOL $GET  
$OPEN $PUT  
$PARSE $RELEASE  
$REMOVE $REWIND  
$RENAME 1 $TRUNCATE  
$SEARCH $UPDATE  
  $WAIT  

1Denotes macro with nonstandard format (see text).

After calling a service, you should check the status code returned in R0 (and the STS field of the appropriate control block). The recommended way to signal errors is to provide both the STS and STV fields of the FAB or RAB as arguments to the appropriate run-time library routine. The following VAX MACRO instructions invoke the LIB$SIGNAL routine for a file-related (FAB) error using the CALLS (stack) form of calling a routine, where the FAB is located at symbolic address MYFAB (not shown):


PUSHL  MYFAB+FAB$L_STV          ; Push fields on stack
PUSHL  MYFAB+FAB$L_STS          ; in reverse order
CALLS  #2, G^LIB$SIGNAL         ; Invoke signal routine

B.3 VAX MACRO Example Programs

This section includes examples illustrating the implementation of RMS at the VAX MACRO programming level. See the Guide to OpenVMS File Applications for RMS examples using the Edit/FDL utility.

Using RMS macros, you can create new files, process existing files, extend and delete files, and read, write, update, and delete records within files.

To create and process RMS files, your program must contain calls to appropriate services. Generally, you make these calls by using the service macros for run-time processing. When encountered at run time, the expanded code of these macros generates a call to the corresponding service. Each macro and its resultant call represent a program request for a file or record service, or a block I/O transfer operation.


Previous Next Contents Index