*DECK DB$KMIF 
USETEXT CDCSCTX 
      PROC DB$KMIF(KEYMODE,RECORDNL,ITMORDNL,FIT,DATADRES); 
  
 #
  
  *   DB$KMIF - KEY MAPPER INTERFACE             PAGE  1
  *   STEVEN P. LEVIN                            DATE  12/07/76 
  
  DC  PURPOSE 
  
      THIS MODULE SERVES AS AN INTERFACE BETWEEN OTHER CDCS MODULES 
      WHICH MAY NEED MAPPING FOR KEY OR DATA NAME ITEMS AND THE 
      APPROPRIATE DDL-GENERATED KEY MAPPING CAPSULES.  THIS INTERFACE 
      INCLUDES CONTROLLING OR DOING THE READING TO CORE, RELOCATING,
      PARAMETER PASSING, CALLING, AND ERROR CHECKING FOR KEY CAPSULES.
  
  DC  ENTRY CONDITIONS
  
      THE FOLLOWING PARAMETERS MUST BE PASSED IN THE INDICATED ORDER: 
      KEYMODE  - KEY MAPPER MODE: FALSE IFF DATA NAME, TRUE IFF KEY 
      RECORDNL - RECORD ORDINAL IN THE SUBSCHEMA
      ITMORDNL - ITEM ORDINAL IN THE SUBSCHEMA
      FIT      - FILE INFORMATION TABLE (FIT) 
      DATADRES - DATA NAME ITEM FIRST WORD ADDRESS (FOR RESTRICT ITEM)
      THE FOLLOWING BASED ARRAYS AND ITEM IN CDCSCOMMN MUST BE VALID: 
      ASL       - ACTIVE SUBSCHEMA LIST (POINT TO CURRENT SUBSC ENTRY)
      RCB       - RUN-UNIT COMMAND BLOCK (POINT TO CURRENT ENTRY) 
      RSARBLK   - RSB AREA CONTROL BLOCK (POINT TO CURRENT AREA ENTRY)
      TQT       - TASK QUEUE TABLE (POINT TO CURRENT TASK ENTRY)
      TIMESTAMP - CDCS INTERNAL TIMER (MUST CONTAIN CURRENT CDCS TIME)
  
  DC  EXIT CONDITIONS 
  
      ON NORMAL RETURN FROM DB$KMIF, THE KEY OR DATA NAME ITEM WHICH
      IS INDICATED BY THE PARAMETERS THAT ARE PASSED TO DB$KMIF WILL
      HAVE BEEN MAPPED, IF SUCH MAPPING IS NEEDED.  IN THE CASE OF A
      KEY ITEM (KEYMODE TRUE), THE RETURNED KEY VALUE CAN BE FOUND BY 
      THE CALLER OF DB$KMIF AT THE LOCATION INDICATED BY THE KEY
      ADDRESS (KA) FIELD IN THE FIT, WHOSE VALUE MAY HAVE CHANGED.
      IN THE CASE OF A DATA NAME ITEM, THE RETURNED VALUE CAN BE FOUND
      AT THE LOCATION INDICATED BY THE DB$KMIF PARAMETER DATADRES.
      IF AN ITEM-LEVEL ERROR OCCURS AND THE RUN-UNIT HAS ESTABLISHED
      A DBST THAT CONTAINS THE SECTION OF AUXILIARY STATUS INFORMATION, 
      THEN THE SUBSCHEMA ITEM ORDINAL WILL BE STORED IN THE RCB ENTRY.
      IF AN ERROR IS FOUND DURING PROCESSING OF DB$KMIF OR MODULES
      SUBORDINATE TO IT THROUGH CALLS (INCLUDING THE MAPPING CAPSULE
      ITSELF), DB$ERR OR DB$PUNT WILL BE CALLED, AS APPROPRIATE.
      THUS, MODULES WHICH CALL DB$KMIF DO NOT HAVE TO TEST FOR ERRORS.
  
  DC  CALLING ROUTINES
  
      DB$REL$ - READ RELATION CONTROL SYMBIONT
      DB$SFIT - COMPLETE SETTING OF CERTAIN FIELDS IN THE USER FIT
  
  DC  CALLED ROUTINES 
  
      DB$CALL - CALL A MODULE, GIVEN ITS ADDRESS AS A PARAMETER 
      DB$CEDP - ARRANGE TO CALL ITEM ERROR DBPS 
      DB$ERR  - PROCESS A CDCS OR CRM EXTERNAL ERROR
      DB$FLOP - GENERATE FLOW POINT 
      DB$MBA  - ALLOCATE A "TEMPORARY" MANAGED MEMORY BLOCK, USING CMM
      DB$MBF  - FREE A "TEMPORARY" MANAGED MEMORY BLOCK, USING CMM
      DB$MCAP - GET A MAPPING CAPSULE FROM MD, AND HAVE IT RELOCATED
  
  DC  NON-LOCAL VARIABLES 
  
      THE VALUE OF THE PARAMETER DATADRES MAY BE MODIFIED BY DB$KMIF. 
      THE VALUES OF THE FOLLOWING EXTERNAL ITEMS MAY BE MODIFIED: 
      DB$MBUF - SCRATCH ("TEMPORARY") BUFFER FIRST WORD ADDRESS 
      DB$MDNA - DATA NAME ITEM FIRST WORD ADDRESS (FOR RESTRICT ITEM) 
      DB$MERF - MAPPING ERROR FLAG FOR CAPSULE PROCESSING ERRORS
      DB$MERP - APLIST FWA FOR ITEM-LEVEL ON-ERROR-DURING DB PROCS
      DB$MERR - ERROR INDICATOR FOR NON-CAPSULE PROCESSING ERRORS 
      DB$MFIT - FILE INFORMATION TABLE (FIT) FIRST WORD ADDRESS 
      DB$MFWA - FIRST WORD ADDRESS OF THE MAPPING CAPSULE IN CORE 
      DB$MIOR - ITEM ORDINAL IN THE SUBSCHEMA 
      DB$MKEY - KEY MAPPER MODE: FALSE IFF DATA NAME, TRUE IFF KEY
      DB$MMOD - MAPPER MODE: 0 = WRITE, 1 = REWRITE, 2 = READ, 3 = KEY
      DB$MRBF - RESULT IN BUFFER: TRUE IFF MAPPED RESULT IS IN BUFFER 
      DB$MROR - RECORD ORDINAL IN THE SUBSCHEMA 
      DB$MSSO - SUBSCHEMA ITEM ORDINAL IF ITEM-LEVEL ERROR OCCURS 
      THE ACL POINTER AND ACL FIELDS IN CDCSCOMMN MAY BE MODIFIED.
  
  DC  DESCRIPTION 
  
      IF THERE IS NO KEY CAPSULE FOR THE CURRENT AREA ENTRY, RETURN.
      IF THE KEY CAPSULE IS NOT YET IN CORE, CALL DB$MCAP TO GET IT.
      UPDATE FIELDS IN THE ACL TO INDICATE IMPENDING CAPSULE USAGE. 
      ASSIGN VALUES TO EXTERNAL ITEMS WHICH ARE USED BY THE CAPSULE.
      CALL DB$MBA TO ALLOCATE A "TEMPORARY" CMM BLOCK FOR A BUFFER. 
      CALL DB$CALL TO CALL THE KEY MAPPING CAPSULE FOR EXECUTION. 
      IF DB$MSSO INDICATES THAT AN ITEM-LEVEL ERROR OCCURRED, AND A DBST
      EXISTS THAT INCLUDES THE AUXILIARY STATUS BLOCK, THEN STORE THE 
      SUBSCHEMA ITEM ORDINAL IN THE RCB ENTRY.
      IF THE ERROR FLAG DB$MERF INDICATES AN ERROR, CALL DB$ERR.
      SET THE APLIST FWA FOR ITEM-LEVEL ON-ERROR-DURING DB PROCS TO 0.
      DEPENDING ON DB$MRBF, FREE BUFFER OR POSSIBLY MODIFY DATADRES.
      RETURN FROM DB$KMIF WITH THE MAPPING NOW DONE, IF IT WAS NEEDED.
  
 #
        CONTROL EJECT;
  
        BEGIN                # DB$KMIF #
  
# THE FOLLOWING ARE FORMAL PARAMETERS IN THE ORDER THEY ARE PASSED #
  
        ITEM KEYMODE B;      # KEY MAP MODE: FALSE=DATA NAME,TRUE=KEY#
        ITEM RECORDNL U;     # RECORD ORDINAL IN THE SUBSCHEMA #
        ITEM ITMORDNL U;     # ITEM ORDINAL IN THE SUBSCHEMA #
        ARRAY FIT;;          # FILE INFORMATION TABLE # 
        ITEM DATADRES U;     # DATA NAME ITEM FIRST WORD ADDRESS #
  
# THE FOLLOWING ARE EXTERNALLY REFERENCED PROCEDURES AND ITEMS #
  
        XREF PROC DB$CALL;   # CALL A MODULE, GIVEN ITS ADDRESS # 
        XREF PROC DB$CEDP;   # (ARRANGE TO) CALL ITEM ERROR DBPS       #
        XREF PROC DB$ERR;    # PROCESS A CDCS OR CRM EXTERNAL ERROR # 
        XREF PROC DB$FLOP;   # GENERATE FLOW POINT                     #
        XREF PROC DB$MBA;    # ALLOCATE A "TEMPORARY" MEMORY BLOCK #
        XREF PROC DB$MBF;    # FREE A "TEMPORARY" MEMORY BLOCK #
        XREF PROC DB$MCAP;   # GET A MAPPING CAPSULE FROM THE MD FILE#
        XREF ITEM DB$MBUF U; # SCRATCH BUFFER FIRST WORD ADDRESS #
        XREF ITEM DB$MDNA U; # DATA NAME ITEM FIRST WORD ADDRESS #
        XREF ITEM DB$MERF U; # MAPPING ERROR FLAG FOR CAPSULE ERRORS #
        XREF ITEM DB$MERP U; # APLIST FWA FOR ITEM-LEVEL ERROR DBPS # 
        XREF ITEM DB$MERR U; # ERROR INDICATOR FOR NON-CAPSULE ERRORS#
        XREF ITEM DB$MFIT U; # FILE INFORMATION TABLE WORD ADDRESS #
        XREF ITEM DB$MFWA U; # FIRST WORD ADDRESS OF CAPSULE IN CORE #
        XREF ITEM DB$MIOR U; # ITEM ORDINAL IN THE SUBSCHEMA #
        XREF ITEM DB$MKEY B; # KEY MAP MODE: FALSE=DATA NAME,TRUE=KEY#
        XREF ITEM DB$MMOD U; # MODE:0=WRITE, 1=REWRITE, 2=READ, 3=KEY#
        XREF ITEM DB$MRBF B; # RESULT IN BUFFER:TRUE=MAPPED IN BUFFER#
        XREF ITEM DB$MROR U; # RECORD ORDINAL IN THE SUBSCHEMA #
        XREF ITEM DB$MSSO U; # SS ITEM ORDINAL FOR ITEM-LEVEL ERROR    #
  
        CONTROL NOLIST;      # CDCSCOMMN (ACL ASL RSARBLK TIMESTAMP) #
        CONTROL LIST;        # RESUME THE LISTING OF THE SOURCE CODE #
  
*CALL DBSTDCLS
# THE FOLLOWING DEFS ARE LOCAL TO DB$KMIF # 
  
        DEF DFCAPBUF #26#;   # MAPPING CAPSULE SCRATCH BUFFER LENGTH #
        DEF DFCAPHED #3#;    # MAPPING CAPSULE HEADER LENGTH IN WORDS#
        DEF DFCAPKEY #3#;    # MAPPING CAPSULE KEY MAPPING MODE # 
        DEF DFCAPRED #2#;    # MAPPING CAPSULE READ MAPPING MODE #
        DEF DFCAPREW #1#;    # MAPPING CAPSULE REWRITE MAPPING MODE # 
        DEF DFCAPWRT #0#;    # MAPPING CAPSULE WRITE MAPPING MODE # 
        DEF XCALL # #;       # USED FOR EXTERNAL MODULE CALLS # 
        CONTROL EJECT;
  
# GENERATE A FLOW POINT                                                #
  
        CONTROL IFGR DFFLOP,0;
          DB$FLOP ("KMIF"); 
        CONTROL ENDIF;
  
# IF THERE IS NO KEY CAPSULE FOR THE CURRENT AREA ENTRY, RETURN # 
  
        IF RSARCAPP[0] EQ 0            # IF NO KEY CAPSULE             #
        THEN
          BEGIN 
  
          CONTROL IFGR DFFLOP,0;
            DB$FLOP ("KMIF-1");        # GENERATE A FLOW POINT         #
          CONTROL ENDIF;
  
          RETURN; 
          END 
  
# IF THE KEY CAPSULE IS NOT YET IN CORE, CALL DB$MCAP TO GET IT # 
  
        P<ACL> = ASACLLOC[0] + RSARCAPP[0];      # POINT TO ACL ENTRY#
        IF ACCMLOC[0] EQ 0 THEN XCALL DB$MCAP;   # IF SO, GET CAPSULE#
  
# UPDATE FIELDS IN THE ACL TO INDICATE IMPENDING CAPSULE USAGE #
  
        ACNUMCLS[0] = ACNUMCLS[0] + 1;           # NUMBER OF CALLS #
        ACAGECAP[0] = TIMESTAMP;                 # AGE (LAST CALL) #
  
# ASSIGN VALUES TO EXTERNAL ITEMS WHICH ARE USED BY THE CAPSULE # 
  
        DB$MDNA = DATADRES;            # DATA NAME ITEM WORD ADDRESS #
        DB$MERF = 0;                   # MAPPING ERROR FLAG (CAPSULE)#
        DB$MERP = 0;                   # APLIST FWA OF ITEM ERROR DBP#
        DB$MERR = 0;                   # ERROR INDICATOR (NONCAPSULE)#
        DB$MFIT = LOC(FIT);            # FIT FWA #
        DB$MFWA = ACCMLOC[0];          # FIRST WRD ADDRESS OF CAPSULE#
        DB$MIOR = ITMORDNL;            # ITEM ORDINAL IN SUBSCHEMA #
        DB$MKEY = KEYMODE;             # KEY MAP MODE: F=D NAME,T=KEY#
        DB$MMOD = DFCAPKEY;            # MAPPER MODE IS KEY MAP MODE #
        DB$MRBF = FALSE;               # RESULT IN BUFFER: T=IN BUFFR#
        DB$MROR = RECORDNL;            # RECORD ORDINAL IN SUBSCHEMA #
        DB$MSSO = 0;                   # SS ITEM ORD FOR ITEM-LEVEL ERR#
  
# CALL DB$MBA TO ALLOCATE A "TEMPORARY" CMM BLOCK FOR A BUFFER #
  
        XCALL DB$MBA(DFCAPBUF, DB$MBUF);         # ALLOCATE TEMPORARY#
  
# CALL DB$CALL TO CALL THE KEY MAPPING CAPSULE FOR EXECUTION #
  
        $BEGIN                     #DEBUG TRACE#
        XREF PROC DB$TRCO;
        DB$TRCO("MAP KEY:",0,0);
        $END
        XCALL DB$CALL(DB$MFWA + DFCAPHED);       # CALL KEY CAPSULE # 
  
# CLEAR DB$MFWA SO DB$CMOH IS ALLOWED TO UNLOAD THE CAPSULE.           #
  
        DB$MFWA = 0;
  
# IF AN ITEM-LEVEL ERROR OCCURRED AND A DBST EXISTS THAT INCLUDES THE  #
# AUXILIARY STATUS BLOCK, THEN STORE THE SUBSCHEMA ITEM ORDINAL IN THE #
# RCB ENTRY.                                                           #
  
        IF DB$MSSO NQ 0 
          AND TQDBSTLW[0] GQ DFDBSTAUX
        THEN
          BEGIN 
          RCMSSO[0] = DB$MSSO;
          END 
  
# IF THE ERROR FLAG DB$MERF INDICATES AN ERROR OCCURRED, CALL DB$ERR #
  
        IF DB$MERF NQ 0            # IF SOME MAPPING ERROR OCCURRED    #
        THEN
          BEGIN 
          DB$CEDP;                 # ARRANGE TO CALL ITEM ERROR DBPS   #
          DB$ERR(39);              # KEY MAPPING ERROR MSG             #
          END 
  
  
# SET THE APLIST FWA FOR ITEM-LEVEL ON-ERROR-DURING DB PROCS TO ZERO #
  
        DB$MERP = 0;         # APLIST FWA FOR ITEM-LEVEL ERROR DBPS # 
  
# DEPENDING ON DB$MRBF, FREE THE BUFFER OR POSSIBLY MODIFY DATADRES # 
  
        IF NOT DB$MRBF                 # IF MAP RESULT NOT IN BUFFER #
          THEN XCALL DB$MBF(DB$MBUF);  # FREE THE "TEMPORARY" BUFFER #
          ELSE IF NOT KEYMODE THEN DATADRES = DB$MBUF;     # NEW ADDR#
  
# RETURN FROM DB$KMIF WITH THE MAPPING NOW DONE, IF IT WAS NEEDED # 
  
        RETURN;              # MAPPING NOW DONE, IF IT WAS NEEDED # 
  
        END                  # DB$KMIF #
  
      TERM
