MICRONOTES
================================================================================
Note 14.0                 Fortran Routines from VAXELN                No replies
JAWS::KAISER                                        203 lines  25-MAR-1985 09:20
--------------------------------------------------------------------------------
      +---------------+					   +-----------------+
      | d i g i t a l |					   |  uNOTE # 014    |
      +---------------+					   +-----------------+


      +----------------------------------------------------+-----------------+
      | Title:	    Using Fortran Routines In A		   | Date: 16-Oct-84 |
      |		     VAXELN-Pascal Environment		   |		     |
      +----------------------------------------------------+-----------------+
      | Originator:  Herbert F. Maehner			   | Page 1 of 4     |
      +----------------------------------------------------+-----------------+


      This Micronote discusses the VAXELN interface to	VAX-11	Fortran.   The
      following topics are covered are discussed:

	   1.  The VAX-11 Procedure Calling Standard

	   2.  Establishing a COMMON-data area between a  VAXELN  program
	   and Fortran routines

		      VAXELN Procedure Calling Standard
		      ---------------------------------

      VAXELN Pascal (EPascal)  does  conform  to  the  VAX  Procedure  Calling
      Standard.	  The standard allows for three methods of parameter passing :
      value, reference, and descriptor, and requires that values be no	longer
      than  a  longword.   EPascal  does not explicitly support descriptors as
      parameters, and other languages may not treat conformant	parameters  as
      EPascal does, but EPascal does nothing to violate the calling standard.

      All routines can be described according to the conventions described  in
      the  summary  of run-time library entry points [1].  There are principle
      differences in passing parameters in Pascal and Fortran:

      In Pascal, you may pass parameters as

       - values, e.g PROCEDURE Pass_it (What: INTEGER);

	   i.e.	 the value of the  parameter  will  be	copied	into  the
	   procedure's	stack  frame  with no implications for the source
	   variable.  This is termed pass by value.

      or as

       - variable, e.g. PROCEDURE Pass_it (VAR What: INTEGER);

	   i.e.	 the parameter will be referenced  through  its	 address.
	   An  assignment  to  the  parameter  within  the procedure will
	   directly affect the source variable.	 This is termed	 pass  by
	   reference.

									Page 2



      In Fortran, you pass parameters as

       - values, e.g. SUBROUTINE Passit( What)
		      INTEGER*4 What

	   i.e.	 with no implications for the source.  It uses	a  common
	   data	 area  to  pass	 variables to the main program.	 The main
	   difference to Pascal is, that Fortran uses pass by  reference,
	   although it is actually a value.

      Calling  a  Fortran  routine  with  parameter  passing  from  a	Pascal
      environment,  you	 have  to  declare the parameters as VAR parameters in
      Pascal ( Figure 1 and Figure 2).


			       COMMON Data Area
			       ----------------

      As mentioned before, Fortran uses a COMMON data area to  pass  variables
      from  procedures	to the main part of the program.  In VAX-11 Pascal the
      [COMMON] attribute enables the  linker  to  establish  the  common  data
      section.	VAXELN- Pascal has no such attribute and wouldn't overlay data
      sections for common areas.  To overcome this restriction	you  must  use
      the  [EXTERNAL]  attribute  in  VAXELN-Pascal to declare the prospective
      data as externally declared and use a MACRO-32 declaration to assign the
      Fortran common part to the "global" data area (Figure 3).





	 References:

	 1. VMS RUN TIME LIBRARY USER'S GUIDE (Summary of Run Time
					       Library Entry Points)

	 2. VAXELN Encyclopedia, Procedures and Functions,

	 3. VMS MACRO Language Reference Manual

									Page 3


	  +--------------------------------------------------------------------+
	  |  MODULE Fortran_TO_Pascal;					       |
	  |								       |
	  |  { This module is a simple example on, how to use Fortran	       |
	  |    routines in VAXELN.  }					       |
	  |								       |
	  |  CONST							       |
	  |    Max = 50;						       |
	  |								       |
	  |  TYPE							       |
	  |    Array_type = ARRAY[1..Max] OF INTEGER;			       |
	  |								       |
	  |  VAR							       |
	  |    AA: [EXTERNAL] Array_type;				       |
	  |								       |
	  |  PROCEDURE Valaccess (VAR What:INTEGER); EXTERNAL;		       |
	  |								       |
	  |  FUNCTION Double_it (VAR What: INTEGER):INTEGER; EXTERNAL;	       |
	  |								       |
	  |  PROGRAM FORTEST(INPUT,OUTPUT);				       |
	  |								       |
	  |  VAR							       |
	  |    What,I,J,K:  INTEGER;					       |
	  |    Twenty: [READONLY] INTEGER:=20;				       |
	  |								       |
	  |  BEGIN							       |
	  |    WRITELN('Program start ');				       |
	  |    FOR I:=1 TO Max DO AA[I] := 0; { initialize array }	       |
	  |    Valaccess(Twenty);	 { call Fortran routine Valaccess }    |
	  |    FOR I:=21 TO Max DO					       |
	  |    BEGIN							       |
	  |	 What := I;						       |
	  |	 AA[I] := Double_it(What);     { use Fortran Function to       |
	  |    END;				     double array value }      |
	  |								       |
	  |    {  formated output to screen  }				       |
	  |								       |
	  |    K := 1;							       |
	  |    FOR I:=1 TO 10 DO					       |
	  |    BEGIN							       |
	  |	 FOR J:=1 TO 5 DO					       |
	  |	 BEGIN							       |
	  |	   WRITE(AA[K]:4,'  ');					       |
	  |	   K := K+1						       |
	  |	 END;							       |
	  |	 WRITELN;						       |
	  |    END;							       |
	  |  END;							       |
	  |  END; { end of module Fortran_to_Pascal }			       |
	  |								       |
	  +--------------------------------------------------------------------+
		    Figure 1 : VAXELN main program module

									Page 4



	  +--------------------------------------------------------------------+
	  | C								       |
	  | C Fortran SUBROUTINE TO SET THE INDEXED ARRAY VALUE		       |
	  | C THE MAXIMAL INDEX IS PASSED AS A PARAMETER		       |
	  | C								       |
	  |	 SUBROUTINE VALACCESS(WHAT)				       |
	  |	 IMPLICIT INTEGER*4 (A-Z)				       |
	  | C								       |
	  |	 COMMON	 /XX$AA/ AA(50)					       |
	  | C								       |
	  | C								       |
	  |	 DO 10 I=1,What						       |
	  |	 AA(I) =  What-I					       |
	  | 10	 CONTINUE						       |
	  | C								       |
	  |	 RETURN							       |
	  | C								       |
	  |	 END							       |
	  | C								       |
	  | C								       |
	  | C								       |
	  | C INTEGER FUNCTION TO DOUBLE THE VALUE PASSED AS A PARAMETER       |
	  | C								       |
	  |	 INTEGER FUNCTION DOUBLE_IT(WHAT)			       |
	  |	 IMPLICIT INTEGER*4 (A-Z)				       |
	  |	 DOUBLE_IT = WHAT + WHAT				       |
	  |	 RETURN							       |
	  | C								       |
	  |	 END							       |
	  |								       |
	  +--------------------------------------------------------------------+
		   Figure 2: External Fortran routines used

	  +--------------------------------------------------------------------+
	  | ;								       |
	  | ; definition file for common array AA to be accessed by Fortran    |
	  | ; subroutine VALACCESS					       |
	  | ; the P-section name XX$AA must be the same as the one used in the |
	  | ; Fortran routine						       |
	  | ;								       |
	  |	 .TITLE COMDAT						       |
	  |	 .PSECT XX$AA,LONG,PIC,USR,OVR,REL,GBL,SHR,NOEXE,RD,WRT,NOVEC  |
	  | AA:: .LONG 50						       |
	  |	 .END							       |
	  |								       |
	  +--------------------------------------------------------------------+
	 Figure 3: MACRO definition module to define the common array