HP 3000 Manuals

Special Considerations and Restrictions [ Switch Programming User's Guide ] MPE/iX 5.0 Documentation


Switch Programming User's Guide

Special Considerations and Restrictions 

There are certain considerations to bear in mind when you use Switch.

General 

General considerations apply no matter what the direction of the
mixed-mode call:

 *  Mixed-mode procedure calls require an increased level of programming
    complexity.

 *  The overhead of Switch can be significant.

 *  Because Switch does no probing on addresses passed by the caller,
    data memory protection faults are likely when you pass in bad
    parameter addresses or lengths.

 *  Since Switch does no parameter type or alignment checking, the target
    procedure must make the necessary checks.

The following considerations apply to a particular direction of
mixed-mode call.

NM--> CM 

When making mixed-mode procedure calls in the direction NM--> CM, the
following considerations apply:

 *  Any CM procedure called from NM code must reside in a CM SL. The SL
    containing the procedure must be accessible via the LOADPROC or
    HPLOADCMPROCEDURE intrinsic.  This may be the system library, a group
    library, or a user library.

 *  Unlike other MPE XL intrinsics, the Switch intrinsics do not promote
    their privilege level.  If your user code calls Switch to access a
    non-Privileged target procedure, the execution level remains
    unchanged.  On the other hand, if your user code calls Switch to
    access a Privileged target, the execution level becomes Privileged
    after the target is accessed.

 *  HP Pascal/XL does not support the equivalent of SPL's option
    variable, and HPSWITCHTOCM knows nothing about such procedures.
    Option variable procedures are implemented in Compatibility Mode by
    pushing a 16- or 32-bit mask on the CM stack immediately before
    calling the procedure.

    You can use the HPSWITCHTOCM intrinsic to call an option variable
    procedure, but it is your responsibility to construct the mask (refer
    to the SPL Reference Manual (30000-90024) for more information on the
    OPTION VARIABLE option) and to describe it to HPSWITCHTOCM as the
    first parameter.  See Example 3-11 for an illustration of the use of
    HPSWITCHTOCM to call an option variable procedure.

Example 3-11.  Stub for Option Variable Target Procedure 

     $subprogram$
     $standard_level 'ext_modcal'$
     $tables off$
     $code_offsets off$
     $xref off$
     $type_coercion 'representation'$

     PROGRAM XAMPL311(input, output);

       CONST
         Pidt_Known           = 0;  { By number }
         Pidt_Name            = 1;  { By name   }
         Pidt_Plabel          = 2;  { By PLABEL }

         System_Sl            = 0;
         Logon_Pub_Sl         = 1;
         Logon_Group_Sl       = 2;
         Pub_Sl               = 3;
         Group_Sl             = 4;

         Method_Normal   = 0;  { Not callable from split stack}
         Method_Split    = 1;  { Callable in split stack mode }
         Method_No_Copy  = 2;  { No-copy method               }

         Parm_Type_Value    = 0;  { value parameter }
         Parm_Type_Word_Ref = 1;  { reference parm, word addr }
         Parm_Type_Byte_Ref = 2;  { reference parm, byte addr }

         Ccg              = 0;  { condition code greater (>) }
         Ccl              = 1;  { condition code less    (<) }
         Cce              = 2;  { condition code equal   (=) }
         All_Ok           = 0;  { Used in status check       }

       TYPE
         BIT8              = 0..255;
         BIT16             = 0..65535;
         BIT8_A1           = $ALIGNMENT 1$ BIT8;
         BIT16_A1          = $ALIGNMENT 1$ BIT16;
         CM_PROC_NAME      = PACKED ARRAY [1..16] OF CHAR;
         GENERIC_BUFFER    = PACKED ARRAY [1..65535] OF CHAR;

         SCM_PROCEDURE        =
           PACKED RECORD
           CASE p_proc_id_type : BIT8 OF
             Pidt_Known: (p_fill    : BIT8_A1;
                          p_proc_id : BIT16_A1);
             Pidt_Name: (p_lib       : BIT8_A1;
                         p_proc_name : CM_PROC_NAME);
             Pidt_Plabel: (p_plabel : BIT16_A1);
           END;  { record }

Example 3-11.  Stub for Option Variable Target Procedure, continued 

         SCM_IO_TYPE      = SET OF (input_parm, output_parm);

         PARM_DESC            =
           PACKED RECORD
           pd_parmptr         : GLOBALANYPTR;
           pd_parmlen         : BIT16;
           pd_parm_type       : BIT16;
           pd_io_type         : SCM_IO_TYPE;
           END;

         SCM_PARM_DESC_ARRAY  = ARRAY [0..31] OF PARM_DESC;

         CCODE_TYPE           = shortint;

         XLSTATUS             =
           RECORD
           CASE INTEGER OF
             0: (all : INTEGER);
             1: (info   : SHORTINT;
                 subsys : SHORTINT);
           END;  { record }

       PROCEDURE HPSWITCHTOCM; INTRINSIC;

       PROCEDURE HPSETCCODE; INTRINSIC;

       PROCEDURE QUIT; INTRINSIC;

     { End of OUTER BLOCK GLOBAL declarations }

      PROCEDURE FCHECK  $ALIAS 'FCHECK'$
                 (
                FILENUM : SHORTINT;
            VAR ERRORCODE : SHORTINT;
            VAR TLOG : SHORTINT;
            VAR BLKNUM : INTEGER;
            VAR NUMRECS : SHORTINT
                 );

         VAR
           proc               : SCM_PROCEDURE;
           parms              : SCM_PARM_DESC_ARRAY;
           method             : INTEGER;
           nparms             : INTEGER;
           funclen            : INTEGER;
           funcptr            : INTEGER;
           byte_len_of_parm   : BIT16;
           cond_code          : CCODE_TYPE;
           status             : XLSTATUS;
           mask               : BIT16;

Example 3-11 Stub for Option Variable Target Procedure, continued 

      VAR loc_FILENUM : SHORTINT;

      begin { STUB procedure FCHECK }

       { Initialization }

       { Setup procedure information--name, lib, etc. }

       proc.p_proc_id_type :=  Pidt_Name; { By name }
       proc.p_lib          :=  System_Sl; { Library }
       proc.p_proc_name    :=  'FCHECK          ';

       { Setup misc. variables }

       mask              :=  0;
       method            :=  Method_Normal;  { Split stack? }
       nparms            :=  6;              { 5 + mask }

       { Setup length/pointers for functional return if this }
       { is a FUNCTION.  Set length to zero, pointer to NIL  }
       { if this is not a FUNCTION.                          }

       funclen           :=  0;    { Not a function }
       funcptr           :=  0;

       { Make a local copy of all VALUE parameters }

       loc_FILENUM := FILENUM;

       { Build parameter descriptor array to describe each }
       { parameter.                                        }

       { FILENUM -- Input Only by VALUE }

       byte_len_of_parm := 2;

       mask := binary('10000');
       parms[0].pd_parmptr   := ADDR(loc_FILENUM);
       parms[0].pd_parmlen   := byte_len_of_parm;
       parms[0].pd_parm_type := Parm_Type_Value;
       parms[0].pd_io_type   := [Input_Parm];

       { ERRORCODE -- Output Only by REFERENCE }

       byte_len_of_parm := 2;

       mask := ior16(mask, binary('01000'));
       parms[1].pd_parmptr   := ADDR(ERRORCODE);
       parms[1].pd_parmlen   := byte_len_of_parm;
       parms[1].pd_parm_type := Parm_Type_Word_Ref;
       parms[1].pd_io_type   := [Output_Parm];

Example 3-11.  Stub for Option Variable Target Procedure, continued 

       { TLOG -- Output Only by REFERENCE }

       byte_len_of_parm := 2;

       mask := ior16(mask, binary('00100'));
       parms[2].pd_parmptr   := ADDR(TLOG);
       parms[2].pd_parmlen   := byte_len_of_parm;
       parms[2].pd_parm_type := Parm_Type_Word_Ref;
       parms[2].pd_io_type   := [Output_Parm];

       { BLKNUM -- Output Only by REFERENCE }

       byte_len_of_parm := 4;

       mask := ior16(mask, binary('00010'));
       parms[3].pd_parmptr   := ADDR(BLKNUM);
       parms[3].pd_parmlen   := byte_len_of_parm;
       parms[3].pd_parm_type := Parm_Type_Word_Ref;
       parms[3].pd_io_type   := [Output_Parm];

       { NUMRECS -- Output Only by REFERENCE }

       byte_len_of_parm := 2;

       mask := ior16(mask, binary('00001'));
       parms[4].pd_parmptr   := ADDR(NUMRECS);
       parms[4].pd_parmlen   := byte_len_of_parm;
       parms[4].pd_parm_type := Parm_Type_Word_Ref;
       parms[4].pd_io_type   := [Output_Parm];

       { mask parameter }

       parms[5].pd_parmptr   := ADDR(mask);
       parms[5].pd_parmlen  := byte_len_of_parm;
       parms[5].pd_parm_type := parm_type_value;
       parms[5].pd_io_type  := [Input_Parm];

       { Do the actual SWITCH call }

       HPSWITCHTOCM(proc,         { Procedure info          }
                    method,       { Split stack ?           }
                    nparms,       { Number of parameters    }
                    parms,        { Parm descriptor array   }
                    funclen,      { func ret value length   }
                    funcptr,      { Addr of func return     }
                    cond_code,    { cond. code return       }
                    status);      { SWITCH status code      }

       if (status.all <> all_ok) then
         BEGIN { SWITCH subsystem error }
            QUIT(status.info);
         END;  { SWITCH subsystem error }

Example 3-11.  Stub for Option Variable Target Procedure, continued 

       HPSETCCODE(cond_code);

       end; { STUB procedure FCHECK }

       BEGIN { Program Outer block code }

       END.  { Program Outer block code }

     {end Example 3-11}


MPE/iX 5.0 Documentation