VAX Professional: The Callable TPU Interface


The Callable TPU Interface


Hunter Goatley

VAXTPU (VAX Text Processing Utility, hereafter referred to as TPU) was introduced with VAX/VMS version 4.2. TPU is a programmable text processing utility that allows applications programmers to easily write editing interfaces and extend interfaces already written in TPU. TPU provides a compiler and an interpreter for the TPU language. One of the editing interfaces written in TPU is the “new” EVE editor, an editor that allows great flexibility (though the default key definitions don’t show it).

DEC provides a series of callable procedures that allow applications to invoke TPU without spawning a DCL subprocess. Using these routines, your application can call an editor written in TPU as easily as any other subroutine. There are two callable interfaces to TPU – a simplified interface and a full interface (the simplified interface calls the full interface to actually invoke TPU). The callable interfaces are described in the VAX/VMS Manual, Utility Routines.

Regardless of the interface used to invoke TPU, the actual call is accomplished by linking to the shareable TPU image, SYS$LIBRARY:TPUSHR.EXE. When you link a program that calls TPU, you can specify the shareable image to the linker. However, the VMS linker is capable of determining what you are doing and will automatically link you to the shareable image.


The simplified interface consists of two routines, TPU$TPU and TPU$EDIT. TPU$TPU accepts one parameter, which is a string in the format of a DCL command normally used to invoke EVE:


TPU$TPU calls routines in the full interface to parse the string and invoke TPU. Ultimately, the utility routine CLI$DCL_PARSE is called to parse the string as a DCL command. The other routine in the simplified interface, TPU$EDIT, accepts an input file name and an output file name as parameters. This routine takes the given file names, creates a DCL command string using them, and then calls TPU$TPU. TPU$EDIT is by far the easiest way to invoke callable TPU, since only an input file is needed. The simplified interface is indeed “simple,” and is probably perfect for most applications needing to call TPU.

Problems using TPU$TPU and TPU$EDIT

While reading about callable TPU, I decided that TPU$EDIT was the routine I would call from one of my programs. My program was using the CLI routines to parse commands and make queries about the elements of the command line. When I added the call to TPU, the editor was invoked as expected. All appeared fine until my routine later made a call to CLI$PRESENT to see if a certain qualifier had been given on the command line. The CLI routine signalled an error, “Specified entity not found in command tables.” The routine had worked fine before I added the call to TPU$EDIT, so I knew that it was somehow responsible for the problem.

Before long, I realized that my routine and TPU$EDIT were both calling the CLI routines. The problem turned out to be that CLI$DCL_PARSE needs the address of a command table to parse a command. When my program first called CLI$DCL_PARSE, the command table for my program was established as the command table for subsequent calls to the other CLI routines. Because TPU$EDIT was also calling CLI$DCL_PARSE, TPU’s CLI command table was superseding mine. When my routine called CLI$PRESENT after calling TPU$EDIT, the CLI routine was still using TPU’s CLI command table, not mine. Hence the error that was signalled. One solution was to call CLI$DCL_PARSE again before I called CLI$PRESENT, but I felt that was unnecessarily sloppy. The other solution left to me was to use the full callable TPU interface.

The full TPU interface isn’t exactly easy to use (at least not as easy as I wanted). So I decided to write my own simplified interface that did what DEC’s should have done to begin with – allow various parameters to be passed in and then call the full interface routines without calling the CLI routines. I can see a couple of reasons for DEC’s approach (TPU$TPU uses a command line that is already familiar to a TPU user), but the simplified interface sure is inefficient. If you call TPU$EDIT, you’re really calling TPU$TPU, which calls TPU$CLIPARSE, which in turn calls CLI$DCL_PARSE, just to find the names of the input file and output file that you originally passed in to TPU$EDIT! (OK, there are a couple of other defaults that this handily takes care of, but still..)

The design for my simplified interface, TPU_EDIT (Program 1), was based on DEC’s callable EDT routine (also described in the Utility Routines manual). My routine allows you to pass in everything that could be specified on the DCL command line. This approach seems to give all of the flexibility that TPU$TPU allows, without introducing the complexity (and without calling the CLI routines!). The parameters that can be passed are as follows:

  1. The name of the input file
  2. The name of the output file
  3. The name of the command file (corresponds to /COMMAND)
  4. The name of the section file (corresponds to /SECTION)
  5. The name of the journal file (corresponds to /JOURNAL)
  6. An options bit mask that indicates options to be used (/CREATE, /DISPLAY, etc.)

All of the parameters are optional except the input and output file name. An example of calling TPU_EDIT from BASIC would look like this:



Before describing my simplified TPU interface, I will provide brief descriptions of the 10 routines that make up the full callable TPU interface. For detailed descriptions of each of these routines, see the VAX/VMS manual Utility Routines.


As the name implies, this routine is called to initialize TPU. This routine performs the allocation of global data structures and calls the initialization routines for the major parts of the editor (screen management routines, I/O routines, etc.). It accepts one argument, the address of a callback routine that returns the address of an item list describing the initialization parameters. There are nine items that can be specified in the item list, including the name of the section file, the name of the input file, and the name of the output file. TPU$INITIALIZE defaults all strings to the null string. Two items that cannot be defaulted are the FILEIO routine (the routine that performs all file I/O operations) and the CALLUSER routine.


This routine is the default error handler for TPU. It calls the system service SYS$PUTMSG to format the text of error messages and then calls another TPU$ routine to print the message to the screen (TPU$MESSAGE). For non-fatal errors, the handler returns with a continue status, allowing the TPU procedure to continue executing. If the error is fatal or is not a TPU error, the error is resignaled (usually resulting in a fatal TPU error and a nice little message about submitting an SPR).


This routine will allow you to execute a user-written TPU initialization file. If used, this routine must be called after TPU$INITIALIZE and before any other TPU$ routines. If a section file was successfully mapped in by TPU$INITIALIZE, the TPU procedure TPU$INIT_PROCEDURE is located and executed. If a command file was given, it is then read into a buffer, compiled, and executed.


This is the main routine for callable TPU; it reads keystrokes and performs all of the editing functions. Before calling this routine, TPU$INITIALIZE must be called. Once this routine takes control, the user’s program will not receive control until the user leaves the editor (either by quitting or exiting).


When TPU is no longer needed, this routine is called to release data structures, close the section file, reset the terminal characteristics, and perform other cleanup tasks. It accepts one parameter, the address of a longword bit mask that describes the various cleanup options. When this routine is called, you can have it perform only certain jobs (such as deleting buffers and windows) or delete the entire TPU editing context (TPU$M_DELETE_CONTEXT).


This routine provides access to the built-in TPU function MESSAGE. It can be called by a user routine to print a message that is consistent with TPU’s messages. It accepts one parameter, the address of a string descriptor that points to the message text.


This routine allows a non-TPU user-routine to execute TPU commands. It accepts the TPU command as a string. This routine performs the same function as the TPU built-in command EXECUTE.


This routine is TPU’s default file I/O routine. It can be specified in the TPU$INITIALIZE item list as the FILEIO routine.


These routines are used to parse a command string and build an item list to pass to TPU$INITIALIZE. Both routines call the CLI (Command Language Interpreter) utility routines to determine what information was passed on the command line.

TPU_EDIT – My Simplified TPU Interface

The calling sequence for the full TPU interface is straight-forward:

  1. Establish a condition handler (TPU$HANDLER, in this case).
  2. Initialize the TPU structures (TPU$INITIALIZE).
  3. Execute the TPU procedure TPU$INIT_PROCEDURE in the section file that was opened (TPU$EXECUTE_INIFILE).
  4. Turn control ovur to TPU (TPU$CONTROL).
  5. Clean up by releasing memory no longer needed, closing files, etc. (TPU$CLEANUP)

Step 1 – The Error Handler

The first step in calling TPU is to establish a condition handler to take care of errors that may occur. For my purposes, the default TPU condition handler (TPU$HANDLER) was fine; from MACRO, establishing a condition handler takes only a single instruction:


This instruction moves the handler’s address to the top of the current call frame (pointed to by the Frame Pointer – FP). From a high-level language, you can call the Run-Time Library routine LIB$ESTABLISH to establish a condition handler.

Step 2 – Calling TPU$INITIALIZE

The second step, calling TPU$INITIALIZE, proved to be the most complicated part of the process. TPU$INITIALIZE uses an item list that describes initialization parameters; however, its parameter is the address of a routine that TPU$INITIALIZE calls. This callback routine returns the address of the item list. For an application that needs to call TPU and has a static item list, this is trivial; the callback routine simply moves the address of the item list into R0 and returns. But because I wanted to provide a flexible interface that would allow calling routines to omit arguments, my callback routine is a little more complex.

The item list that TPU$INITIALIZE needs is an array of item descriptors (see Figure 1). There is an item code for each piece of information that can be included in the item list. For example, the item code for the input file is TPU$K_INPUTFILE. Each of the item codes (as well as error codes) is declared as a global constant by the TPU shareable image. When you link your program with the shareable image, all references to these constants are resolved. The item descriptor for the input file consists of the length of the input file name, the item code, the address of the input file name string, and a return address (0 for item descriptors). The item descriptors can be passed in any order; the list is terminated with a descriptor whose fields are zero.

When passing procedure addresses in TPU, a Bound Procedure Value (BPV) is used. A BPV consists of two longwords: the first longword is the address of the routine and the second is the environment value (a value that is passed to your routine in R1). It is the address of the BPV for your callback routine that is passed to TPU$INITIALIZE.

The code for my callback routine checks the arguments originally passed to TPU_EDIT. If an argument is omitted (or 0 is passed in), certain defaults are used to make this routine consistent with the DCL-TPU interface:

  • If an options mask is not passed in, a default mask is used. This mask matches all options that normally default with the DCL command.
  • If no section file is passed, the default is TPUSECINI.
  • If no command file is passed, the routine checks to see if a TPUINI file exists. If it does, it is used as the command file.
  • If no journal file name is passed, the name defaults to the name of the input file.

For each of the arguments passed to the routine, an item descriptor is added to the item list. The FILEIO item always defaults to TPU$FILEIO. When the item list is complete, the callback routine places its address in R0 and returns to TPU$INITIALIZE, which continues the TPU initialization.


Before control can be turned over to TPU, TPU$INIT_PROCEDURE in the section file must be executed. For EVE, this procedure creates all of the buffers, windows, etc., necessary for EVE to work. This third step is accomplished by simply calling TPU$EXECUTE_INIFILE.

Step 4 – Calling TPU$CONTROL

The routine is now ready to turn control over to TPU by calling TPU$CONTROL. TPU reads all of the keystrokes and performs all of the editing functions. Control does not return to my routine until the user exits the editor.

TPU$CONTROL returns one of two condition values: TPU$_EXITING (returning because of EXIT) and TPU$_QUITTING (returning because of QUIT). One detail not mentioned anywhere is that these condition values, when returned by TPU$CONTROL, have bit 28 turned on; this bit, when set, prevents any message from being printed on image exit. This is fine unless your program wants to check which of these values was returned. Normally, bit 28 is clear; if your program simply compares the return value with TPU$_EXITING, they will not be equal, even if the user did EXIT. TPU_EDIT clears this bit before returning it to the caller, allowing calling programs to check for these two conditions.

Step 5 – Calling TPU$CLEANUP

The final step is to call TPU$CLEANUP to release unneeded memory. The address of a bit mask that denotes the cleanup options is passed to TPU$CLEANUP. All of the cleanup options available appear in the VMS manual entry for TPU$CLEANUP. My routine asks TPU$CLEANUP to do all cleanup options except closing the section file. By leaving the section file open, processing time is decreased the next time the main routine invokes TPU. My routine works like TPU$TPU in this respect.

Linking with TPU_EDIT and TPU

To assemble TPU_EDIT and link it with a program, simply write the calling program (called CALL_EDITOR in the example), and compile and link as you normally would:


When you run CALL_EDITOR, TPU will be invoked without spawning a subprocess.

As I said earlier, calling TPU$EDIT will be sufficient for invoking TPU from most programs. If you encounter the problem I had, TPU_EDIT will provide the same functionality. Either way, you should now be more familiar with the callable TPU interface.

Biographical Information

Hunter Goatley, a graduate in Computer Science from Western Kentucky University, is currently working as a programmer/analyst for Clyde Digital Systems, Orem, Utah.

+-----------------------------------------------+ +0
|                       |                       |
|       Item code       |     Buffer Length     |
|                       |                       |
|-----------------------------------------------| +4
|                                               |
|                 Buffer address                |
|                                               |
|-----------------------------------------------| +8
|                                               |
|       Return address (0 for item lists)       |
|                                               |

            Figure 1  -- Item descriptor

+-----------------------------------------------+ +0
|                                               |
|               Procedure address               |
|                                               |
|-----------------------------------------------| +4
|                                               |
|       Environment Value (passed in R1)        |
|                                               |

               Figure 2  -- BPV



        .TITLE  TPU_EDIT - Provide simplified callable interface to VAXTPU
        .IDENT  /01-001/
;  Routine:     TPU_EDIT
;  Author:      Hunter Goatley
;               Clyde Digital Systems
;               371 East 800 South
;               Orem, Utah  84058
;               (801) 224-5306
;  Date:        November 7, 1987
;  Functional Description:
;       This routine provides a simple interface to callable VAXTPU.  This
;       routine differs from DEC's simplified interfaces in that parameters
;       are passed to this routine, which then sets up a TPU initialization
;       item list and calls the full callable TPU interface.
;       This routine is necessary because DEC's simplified interface routines
;       call the routine TPU$PARSEINFO, which in turn calls CLI$DCL_PARSE.
;       This poses a problem if the calling program is also using the CLI
;       parsing routines because any call to a CLI$ routine after the TPU
;       invocation is unknowingly using TPU's CLI table!  The CLI$ routines
;       do not change command tables until another call to CLI$DCL_PARSE is
;       made.
;  Modified by:
;       01-001          Hunter Goatley           7-NOV-1987 11:36
;               Original version.

;  Argument offsets from (AP)
INFILE          = 1 * 4                         ; Arg 1 = input file spec
OUTFILE         = 2 * 4                         ; Arg 2 = output file spec
COM_FILE        = 3 * 4                         ; Arg 3 = command file spec
SEC_FILE        = 4 * 4                         ; Arg 4 = section file spec
JOU_FILE        = 5 * 4                         ; Arg 5 = journal file spec
OPTIONS         = 6 * 4                         ; Arg 6 = options mask

        $SSDEF                                  ; System service status symbols
        $STSDEF                                 ; STS$ condition symbols
        $LIBDEF                                 ; LIB$ status symbols

;    Read-only data

INIT_ARGS:      .LONG   1                       ; TPU$INITIALIZE argument list
                .ADDRESS CALLBACK_BPV           ; ... Bound Procedure Value
                                                ; ... for callback routine
CALLBACK_BPV:                                   ; Bound Procedure Value
                .ADDRESS INITIALIZE_CALLBACK    ;   Address of routine
                .LONG   0                       ;   Environment (passed in R1)
CLEAN_ARGS:     .LONG   1                       ; TPU$CLEANUP argument list
                .ADDRESS CLEANUP_FLAG           ; ... Cleanup options
FILEIO_BPV:     .ADDRESS TPU$FILEIO             ; BPV for FILEIO routine
                .LONG   0                       ;  (points to TPU$FILEIO)
FINDINI:        .LONG   4                       ; LIB$FIND_FILE argument list
                .ADDRESS TPUINI                 ;   Addr of TPUINI
                .ADDRESS WORK_BUFFER            ;   Addr for resultant spec
                .ADDRESS INICONTEXT             ;   The search context
                .ADDRESS TPUINI_DEF             ;   The SYS$DISK:[] string
FINDINI2:       .LONG   1                       ; LIB$FIND_FILE_END arg. list
                .ADDRESS INICONTEXT             ;   The search context
TPUSECINI:      .ASCID  /TPUSECINI/             ; TPU section file logical
                .ALIGN  LONG                    ; Align on longword boundary
TPUINI:         .ASCID  /TPUINI/                ; Default spec for command file
                .ALIGN  LONG                    ; Align on longword boundary
TPUINI_DEF:     .ASCID  /SYS$DISK:[].TPU/       ; Default spec for TPUINI file

;    Read/Write data

;  Item list returned to TPU$INITIALIZE.  This list provides all information
;  about all of the TPU options selected.  The FILEIO descriptor is always
;  present in the list.
ITEM_LIST:      .WORD   4                       ; Item list descriptor for
                .WORD   TPU$K_FILEIO            ; ... FILEIO routine (points
                .ADDRESS FILEIO_BPV             ; ... to BPV for default TPU
                .LONG   0                       ; ... routine (TPU$FILEIO)
; Variable portion of item list
VAR_ITEM_LIST:  .LONG   0[9*3*4]                ; Up to 9 additional items
                                                ; ...  (including end of list)
ORIG_ARGS:      .BLKL   10                      ; Space for argument list copy
INICONTEXT:     .LONG   0                       ; LIB$FIND_FILE search context
WORK_BUFFER:    .LONG   256                     ; Temporary work buffer
                .ADDRESS .+4                    ; ...  for LIB$FIND_FILE
                .BLKB   256                     ; ...

;       This routine copies its argument list to ORIG_ARGS, establishes the
;       default TPU condition handler (TPU$HANDLER) as its handler, and calls
;       the initialization routines to invoke VAXTPU.
;       4(AP)   - Address of input file name descriptor
;       8(AP)   - Address of output file name descriptor
;       12(AP)  - Address of command file name descriptor (/COMMAND)
;                 (Optional - defaults to TPUINI)
;       16(AP)  - Address of section file name descriptor (/SECTION)
;                 (Optional - defaults to TPUSECINI)
;       20(AP)  - Address of journal file name descriptor (/JOURNAL)
;                 (Optional - defaults to input_file.TJL)
;       24(AP)  - Address of longword options mask  (Optional)
;       Options mask bits:
;               TPU$M_CREATE    - create input file if the one specified
;                                 does not exist  (DEFAULT)
;               TPU$M_DISPLAY   - Attempts to use the terminal for screen-
;                                 oriented editing  (DEFAULT)
;               TPU$M_OUTPUT    - Writes the modified input file on exiting
;                                 (DEFAULT)
;               TPU$M_SECTION   - Maps in a VAXTPU section file on startup
;                                 (DEFAULT)
;               TPU$M_COMMAND   - Executes a command file during startup
;                                 (DEFAULT)
;               TPU$M_JOURNAL   - Journals the edit session  (DEFAULT)
;               TPU$M_READ      - Makes main buffer READ_ONLY edit session
;               TPU$M_RECOVER   - Performs a recovery operation
;       ORIG_ARGS       - Copy of this routine's argument list
;       INIT_ARGS       - Argument list for TPU$INITIALIZE
;       CLEAN_ARGS      - Argument list for TPU$CLEANUP
;       None.
;       LIB$_WRONUMARG  - The wrong number of arguments was specified
;       TPU$_EXITING    - User EXITed from editor
;       TPU$_QUITTING   - User QUIT from editor
;       Any other code returned by TPU$INITIALIZE, TPU$EXECUTE_INIFILE,
;       Invokes TPU.  The section file is not closed as part of the cleanup
;       for efficiency on subsequent calls.

        .ENTRY  TPU_EDIT,^M<R2,R3,R4,R5>
        CMPW    #2,(AP)                         ; Were at least 2 parms given?
        BGTRU   10$                             ; Yes - we're OK
        CMPW    #6,(AP)                         ; Were at most 6 parms given?
        BGEQU   20$                             ; Yes - we're OK
10$:    MOVL    #LIB$_WRONUMARG,R0              ; No - return insufficient args
        RET                                     ; ...  to caller
20$:    MOVAB   G^TPU$HANDLER,(FP)              ; Set up condition handler to be
                                                ; ... the default TPU handler
        MOVZWL  (AP),R0                         ; Get the number of args
        ASHL    #2,R0,R0                        ; Multiply by 4
        ADDL2   #4,R0                           ; Bump R0 by 4
        MOVC3   R0,(AP),ORIG_ARGS               ; Copy argument list
        CALLG   INIT_ARGS,G^TPU$INITIALIZE      ; Initialize TPU
        BLBC    R0,30$                          ; Error?  Return it
        CALLS   #0,G^TPU$EXECUTE_INIFILE        ; Execute the initialization
        BLBC    R0,30$                          ; Error?  Return it
        CALLS   #0,G^TPU$CONTROL                ; Turn control over to VAXTPU
        BLBC    R0,30$                          ; Error?  Return it
        PUSHL   R0                              ; Save the status
        CALLG   CLEAN_ARGS,G^TPU$CLEANUP        ; Clean up
        BLBC    R0,30$                          ; Error?  Return it
        POPL    R0                              ; Restore TPU$CONTROL status
30$:    BICL2   #STS$M_INHIB_MSG,R0             ; Turn off inhibit message
                                                ; ...  on image exit
        RET                                     ; Return to caller

;  Functional description:
;       This routine is called by TPU$INITIALIZE to set up the initialization
;       parameters item list.  The address of the item list is returned to
;       This routine builds the item list from the arguments passed in to the
;       main routine, TPU_EDIT.  It accesses the argument list copy made by
;       TPU_EDIT.
;       The item list always contains at least 4 items:  the input file, the
;       output file, the options mask, and the FILEIO routine (TPU$FILEIO).
;  Register usage:
;       R2  - Points to current location in item list buffer
;       R3  - Copy of the OPTIONS mask passed to TPU
;       R4  - Points to copy of TPU_EDIT's argument list (acts as AP)
        MOVAL   ORIG_ARGS,R4                    ; Get address of original args
        MOVAB   VAR_ITEM_LIST,R2                ; Get the item list address
;  Branch to subroutines to build the item list descriptors for each of the
;  arguments passed in.  The GET_OPTIONS subroutine must be executed first
;  because the other routines access the copy of the options mask placed in
        BSBW    GET_OPTIONS                     ; Get the options to use
        BSBW    GET_JOURNAL                     ; Get the journal file
        BSBB    GET_SECTION                     ; Get the section file
        BSBB    GET_COMMAND                     ; Get the command file
;  Get the output file
        MOVQ    @OUTFILE(R4),R0                 ; Get output file descriptor
        MOVW    R0,(R2)+                        ; Set the length
        MOVW    #TPU$K_OUTPUTFILE,(R2)+         ; Code is OUTPUTFILE
        MOVL    R1,(R2)+                        ; Address of output file name
        CLRL    (R2)+                           ; Return address is 0
;  Get the input file
        MOVQ    @INFILE(R4),R0                  ; Get input file descriptor
        MOVW    R0,(R2)+                        ; Set the length
        MOVW    #TPU$K_FILENAME,(R2)+           ; Code is FILENAME
        MOVL    R1,(R2)+                        ; Address of output file name
        CLRL    (R2)+                           ; Return address is 0

        CLRQ    (R2)+                           ; Clear 3 longwords to signal
        CLRL    (R2)+                           ; ... the end of the item list

        MOVAB   ITEM_LIST,R0                    ; Now return item list address
        RET                                     ; ... to TPU$INITIALIZE

;  This routine builds the item descriptor for the TPU section file.
;  If a file spec is passed in as an argument, it is used as the section
;  file.  If there is no file spec passed in, TPUSECINI is used.
        BBC     #TPU$V_SECTION,R3,30$           ; No SECTION if option bit clear
        CMPB    #4,(R4)                         ; Were there 4 arguments?
        BGTRU   10$                             ; No - use default TPUSECINI
        TSTL    SEC_FILE(R4)                    ; Was a section file specified?
        BEQLU   10$                             ; No - use default(s)
        MOVQ    @SEC_FILE(R4),R0                ; Yes - get section descriptor
        BRB     20$                             ; Go clear return addr and RSB
10$:    MOVQ    TPUSECINI,R0                    ; Default is TPUSECINI
;  Here, a file name descriptor is in R0 & R1
20$:    MOVW    R0,(R2)+                        ; Set the length in item list
        MOVW    #TPU$K_SECTIONFILE,(R2)+        ; Code is SECTIONFILE
        MOVL    R1,(R2)+                        ; Address of section file name
        CLRL    (R2)+                           ; Return address is 0
30$:    RSB                                     ; Return to caller

        BBC     #TPU$V_COMMAND,R3,30$           ; No COMMAND if option bit clear
        CMPB    #3,(R4)                         ; Were there 3 arguments?
        BGTRU   10$                             ; No - go to next
        TSTL    COM_FILE(R4)                    ; Was a command file given?
        BEQLU   10$                             ; No - go to next
        MOVQ    @COM_FILE(R4),R0                ; Get command file descriptor
        BRB     20$                             ; Go set up item descriptor
10$:    CLRL    INICONTEXT                      ; Clear find file context
        CALLG   FINDINI,G^LIB$FIND_FILE         ; Look for initialization file
        PUSHL   R0                              ; Save result for a sec
        CALLG   FINDINI2,G^LIB$FIND_FILE_END    ; Clean up search context
        POPL    R0                              ; Get FIND_FILE result
        BLBC    R0,30$                          ; If FNF, don't pass name in
        MOVQ    TPUINI,R0                       ; Use TPUINI as the command file
20$:    MOVW    R0,(R2)+                        ; Set the length
        MOVW    #TPU$K_COMMANDFILE,(R2)+        ; Code is COMMANDFILE
        MOVL    R1,(R2)+                        ; Address of command file name
        CLRL    (R2)+                           ; Return address is 0
30$:    RSB                                     ; Return to caller

;  Inputs:
;       R2 = Pointer to item list
;  Outputs:
;       R3 = The OPTIONS mask that is passed to TPU
        CMPB    #6,(R4)                         ; Were there 6 arguments?
        BGTRU   10$                             ; No - use default options mask
        TSTL    OPTIONS(R4)                     ; Were any options given?
        BEQLU   10$                             ; No - use default options mask
        MOVAL   @OPTIONS(R4),R1                 ; Yes - put address in R1
        BISL2   #TPU$M_OUTPUT,(R1)              ; Ensure OUTPUT option is set!
        BRB     20$                             ; Go set up the item descriptor
10$:    MOVAL   OPTIONS_MASK,R1                 ; R1 = addr of default options
20$:    MOVW    #4,(R2)+                        ; Length is 4
        MOVW    #TPU$K_OPTIONS,(R2)+            ; Code is OPTIONS
        MOVL    R1,(R2)+                        ; Address
        MOVL    (R1),R3                         ; Copy the options mask to R3
        CLRL    (R2)+                           ; Clear return address
        RSB                                     ; Return to caller

        BBC     #TPU$V_JOURNAL,R3,10$           ; No JOURNAL if option bit clear
        CMPB    #5,(R4)                         ; Were there 5 arguments?
        BGTRU   10$                             ; No - go to next
        TSTL    JOU_FILE(R4)                    ; Was a journal file given?
        BEQLU   10$                             ; No - go to next
        MOVQ    @JOU_FILE(R4),R0                ; Get journal file descriptor
        MOVW    R0,(R2)+                        ; Set the length
        MOVW    #TPU$K_JOURNALFILE,(R2)+        ; Code is JOURNALFILE
        MOVL    R1,(R2)+                        ; Address of journal file name
        CLRL    (R2)+                           ; Return address is 0
10$:    RSB                                     ; Return to caller


 Posted by at 10:44 am