ASMB,L,C,R
      HED RBOPN SUBROUTINE OF RDBA-IMAGE/1000 
      NAM RBOPN,7 92069-16216 REV.2040 800630 
* 
* 
******************************************************************* 
* (C) COPYRIGHT HEWLETT-PACKARD COMPANY 1979. ALL RIGHTS RESERVED.
* NO PART OF THIS PROGRAM MAY BE PHOTOCOPIED, REPRODUCED, OR
* TRANSLATED TO ANOTHER PROGRAM LANGUAGE WITHOUT THE PRIOR WRITTEN
* CONSENT OF HEWLETT-PACKARD COMPANY. 
******************************************************************* 
* 
* 
*     SOURCE:    92069-18216
*     RELOC:     92069-16216
* 
*     PRGMR:     CEJ
*     ALTERED:   June 30, 1980 for bug in clean-up after remote data
*                              base opened. - CEJ 
* 
* 
******************************************************************* 
* 
* 
* 
*  RBOPN is the remote data base DBOPN routine.  Its function is to check 
*  the validity of the DBOPN request, send the request, and build the 
*  RDBA data structures necessary for future remote accesses.  These data 
*  structures consist of: 
*     1)  Data Base Control Block - 
*           a shortened version of the local DBCB with a modified item
*           table and data set table sent from the remote machine.
*     2)  Data Buffer 
*           for sending and receiving data, same structure as used as the 
*           record buffer for local DBMS calls. 
* 
*  The calling sequence for RBOPN is: 
* 
*         JSB RBOPN 
*          DEF *+5        return point
*          DEF BASE       data base parameter from DBOPN call.
*          DEF LEVEL      level code word from DBOPN call.
*          DEF MODE       mode parameter from DBOPN call
*          DEF STAT       status array from DBOPN call
* 
      SKP 
**********************************************************************
*                                                                    *
*  Run Table for local machine in Remote Data Base Access            *
*                                                                    *
*  The local copy of the Run Table used by the RDBA master subrou-   *
*  tines consists of the following sections:                         *
*                                                                    *
*    1) Data Base Control Block                                      *
*    2) Data Item Table                                              *
*    3) Data Set Table                                               *
*    4) Sort Table                                                   *
*                                                                    *
*  These sections are in the order stated.  Details of each section  *
*  follow.                                                           *
*                                                                    *
**********************************************************************
***                                                                ***
*                                                                    *
*  Data Base Control Block - one 17 word entry per data base         *
*                                                                    *
***                                                                ***
RDCBS DEC 17        DBCB size 
* 
RDNAM DEC 0         data base name - three words
      DEC 1 
      DEC 2 
RDRBN DEC 3         remote data base number 
      DEC 4 
RDDSN DEC 5         DS node number
      DEC 6 
RDITC DEC 7         data item count 
RDITP DEC 8         data item table pointer 
RDDSC DEC 9         data set count
RDDSP DEC 10        data set table pointer
RDSOP DEC 11        sort table pointer
      DEC 12
RDLMD DEC 13        lock flag/open mode 
RDLFG EQU RDLMD     1st byte: lock flag 
RDMOD EQU RDLMD     2nd byte: open mode 
      DEC 14
RDCBC DEC 15        # of DCBs desired = 0 
RDMDL DEC 16        maximum data length 
* 
ZERO  EQU RDNAM     base of zero for future equates.
***                                                                ***
*                                                                    *
*  Data Item Table - one 5 word entry per item in a 1000 data base   *
*                                                                    *
***                                                                ***
RI1LN EQU ZERO+5    length of a 1000 entry
* 
RI1NM EQU ZERO      item name - 3 words 
RI1NO EQU ZERO+3    item number 
RI1IL EQU ZERO+4    item length 
***                                                                ***
*                                                                    *
*  Data Set Table - one 6 word entry per set in a 1000 data base     *
*                                                                    *
***                                                                ***
RS1LN EQU ZERO+6    length of a 1000 entry
* 
RS1NM EQU ZERO      set name - 3 words
RS1NO EQU ZERO+3    set number
RS1EL EQU ZERO+4    entry length (in words) 
RS1KL EQU ZERO+5    key item length for a master
***                                                                ***
*                                                                    *
*  Sort Table - one 1 word entry per item and per set.  Each entry   *
*               is a pointer to the respective item or set table     *
*               entry relative to the start of the Run Table         *
*                                                                    *
***                                                                ***
      SKP 
A     EQU 0 
B     EQU 1 
* 
      ENT RBOPN 
      EXT .ENTR,AIRUN,DBFRT,DBPAR,DBRBL,DBRBP,DBRTP,GETBF 
      EXT PNAME,RBBST,RBMST,RETBF,TRIM
* 
BASE  NOP 
LEVEL NOP 
MODE  NOP 
STAT  NOP 
* 
*  Get true parameter and return point addresses. 
* 
RBOPN NOP 
      JSB .ENTR 
       DEF BASE 
* 
*  Ask DBPAR to break the BASE parameter into its components. 
* 
      JSB DBPAR 
       DEF *+3
       DEF NAME 
       DEF BASE,I 
      JMP E103      Error return - illegal base param.
* 
*  Ask DBFRT to make sure that the data base is not already open to us
*  and if not, to give us the index for the next open entry in the Run
*  Table pointer table. 
* 
      CLA           A = 0 tells DBFRT we are DBOPN
      JSB DBFRT 
       DEF *+4
       DEF BASE,I 
       DEF NAME 
       DEF CRN
* 
      SSA,RSS       Did DBFRT find the R.T.?
      JMP E150        Yes - cannot open it again. 
* 
      LDA AIRUN       No - get index from AIRUN 
      STA DBNUM         and save for later. 
      CLA 
      STA AIRUN 
* 
*  Make sure open mode is within [1...8]. 
* 
      LDA MODE,I
      SSA 
      JMP E115      Mode < zero.
      CMA,INA 
      INA,SZA,RSS 
      JMP ROPN1     Mode = 1
      ADA D7
      SSA 
      JMP E115      Mode > 8. 
* 
*  Set maximum size of Run Table to 1899 words. 
* 
ROPN1 LDB D1899 
      STB MAXRT 
* 
*  Ask GETBF to allocate a maximum Run Table for us.  If it cannot, then
*  check the maximum size it has (returned in the error parameter as a
*  negative number).  If this value is greater than 100, set MAXRT to it
*  and ask GETBF to allocate it for us. 
* 
      CCB 
      ADB DBRTP     Get primary pointer 
      ADB DBNUM       for Run Table.
      STB RTPTR 
* 
      JSB GETBF 
       DEF *+4
       DEF MAXRT    GETBF needs: size 
       DEF RTPTR,I               primary pointer
       DEF ERROR        returns: 0 or -(memory available) 
* 
      SSA,RSS       Did we get the max? 
      JMP ROPN2       Yes 
* 
      LDA ERROR       No
      ADA D100        Is there more than 100 words? 
      SSA,RSS 
      JMP E128          No - memory error.
* 
      LDA ERROR         Yes - allocate all the
      CMA,INA             memory that is left.
      STA MAXRT 
* 
      JSB GETBF 
       DEF *+4
       DEF MAXRT
       DEF RTPTR,I
       DEF ERROR
* 
      SSA           Did we get it?
      JMP E160        No - someone's walked on our memory.
* 
*  Save the address of the Run Table pointer in case of a later cleanup.
* 
ROPN2 LDB RTPTR,I 
      STB AIRUN 
* 
*  Build as much of the 17 word DBCB as possible with the information we
*  now have.  This includes:
*  1)  the data base name in the 1st through 3rd words. 
* 
      LDA NAME
      STA B,I 
      INB 
      LDA NAME+1
      STA B,I 
      INB 
      LDA NAME+2
      STA B,I 
* 
*  2)  the remote data base number = two blanks in the 4th word.
* 
      INB 
      LDA BLNKS 
      STA B,I 
* 
*  3)  the DS node number in the 6th word.
* 
      ADB D2
      LDA BASE,I
      STA B,I 
* 
*  4)  the lock flag/open mode in the 14th word.
* 
      ADB D8
      LDA MODE,I
      STA B,I 
* 
*  5)  the number of DCB's (= zero) in the 16th word. 
* 
      ADB D2
      CLA 
      STA B,I 
* 
*  Determine the address for the item and set tables returned by the re-
*  mote DBOPN processor.  This is:  address of allocated Run Table +
*  length of DBCB.
* 
      LDB AIRUN 
      ADB RDCBS 
      STB ADDRS 
* 
*  Determine the length of the maximum item and set tables to return to 
*  us.  This is:  length of allocated Run Table - length of DBCB. 
* 
      LDB RDCBS 
      CMB,INB 
      ADB MAXRT 
      STB INDA
* 
*  Get this program's name.  This is the only data sent with a DBOPN re-
*  quest.  The PNAME subroutine returns our name in the array: NAME.
* 
      JSB PNAME 
       DEF *+2
       DEF NAME 
* 
*  Ask RBMST to build the request buffer, send it, and await the reply. 
* 
      JSB RBMST 
       DEF *+11 
       DEF D36      RBMST needs: RDBA Index 
       DEF MODE,I                open mode
       DEF LEVEL,I               level word (or password) 
       DEF TEMP                  dummy, returns remote DB # here
       DEF BASE,I                data base parameter
       DEF STAT,I                status array 
       DEF NAME                  outgoing data buffer 
       DEF D3                    outgoing data length 
       DEF ADDRS,I               incoming data buffer 
       DEF INDA                  incoming data length 
      JMP RCLN2       error return point
* 
*  The B register has the length of the returned data, save it in INDA. 
* 
      STB INDA
* 
*  No DS error, but check for an IMAGE error code in the first word of
*  the status array.
* 
      LDA STAT,I
      SZA 
      JMP RCLN2 
* 
*  Set the remote data base number, item count, item table pointer, set 
*  count, and set table pointer in the DBCB.  We can get the latter in- 
*  formation from the returned data which looks like: 
* 
*                word        +-------------------------------+
*                   1        |         item count            |
*                            +-------------------------------+
*                   2        |                               |
*                            |             item              |
*                            |            table              |
*                            |                               |
*                            +-------------------------------+
*    item count * item table |         set count             |
*       entry length + 1     +-------------------------------+
*                            |                               |
*                            |             set               |
*                            |            table              |
*                            |                               |
*                            +-------------------------------+
* 
*  The remote data base number is th 4th word of the DBCB and is re-
*  turned by RBMST in TEMP. 
* 
      LDB AIRUN 
      ADB RDRBN 
      LDA TEMP
      STA B,I 
* 
*  The item count is the 8th word of the DBCB 
* 
      ADB D4
      LDA ADDRS,I 
      STA B,I 
* 
*  The item table pointer is the 9th word of the DBCB and is equal to 
*  RDCBS + 1
* 
      INB 
      LDA RDCBS 
      INA 
      STA B,I 
* 
*  The set count is the 10th word of the DBCB and can be found in the 
*  (item count * item table entry length) + 1 word of the returned data 
*  and where the entry length is 5. 
* 
      INB 
      STB TEMP
* 
      LDA ADDRS,I 
      CLB 
      MPY RI1LN 
      INA 
      STA CNTR      CNTR = index to set count in data 
* 
      ADA ADDRS 
      STA ADDRS 
      LDA A,I 
      STA TEMP,I
* 
*  The set table pointer is the 11th word of the DBCB and is equal to the 
*  index to the set count in data + 1 + length of DBCB. 
* 
      ISZ TEMP
      LDA CNTR
      INA 
      ADA RDCBS 
      STA TEMP,I
* 
*  Determine the amount of memory we need to build the sort table.  This
*  is (# of items + # of sets) words. 
* 
      LDB AIRUN 
      ADB RDITC 
      LDA B,I 
      ADB D2
      ADA B,I 
      STA TEMP
* 
*  Determine how much memory we've already used.  This value is equal to
*  the length of the returned data + length of the DBCB.
* 
      LDA INDA
      ADA RDCBS 
* 
*  This value is also the sort table pointer, so put it in the 12th word
*  of the DBCB. 
* 
      LDB AIRUN 
      ADB RDSOP 
      STA B,I 
* 
*  Subtract the already used memory from the Run Table space allocated
*  and check that the remaining space is large enough for the sort table. 
* 
      CMA,INA 
      ADA MAXRT 
      CMA 
      ADA TEMP
      LDB D128
      SSA,RSS 
      JMP RCLN1     Not large enough. 
* 
*  The necessary space is there.  Ask RBBST to build the sort table for us
*  and to return to us the longest entry of any data set in the data base.
* 
ROPN3 JSB RBBST 
       DEF *+2
       DEF CNTR 
* 
*  Add the number of data items or 127, whichever is smaller + 2 (longest 
*  item list) to the longest entry length and this becomes the necessary
*  data (record) buffer length.  Put it in the 17th word of the DBCB. 
* 
      LDA AIRUN 
      ADA RDITC 
      LDB A,I 
      CMB 
      ADB D127
      LDA A,I 
      SSB 
      LDA D127
      ADA D2
      ADA CNTR
      STA CNTR
      LDB AIRUN 
      ADB RDMDL 
      STA B,I 
* 
*  See if we can trim any memory off of our Run Table.  The length of the 
*  full Run Table can now be calculated as: 
*    pointer to sort table + length of sort table (= # of items + # of sets). 
*  Get this length and call TRIM to trim off all allocated memory except for
*  this length. 
* 
      LDB AIRUN 
      ADB RDITC 
      LDA B,I 
      ADB D2
      ADA B,I 
      ADB D2
      ADA B,I 
      STA MAXRT 
* 
      JSB TRIM
       DEF *+3
       DEF RTPTR,I  TRIM needs: primary pointer to buffer 
       DEF MAXRT                length of buffer to keep
* 
      LDB D160      If any error, someone's 
      SSA             walked on our memory. 
      JMP RCLN1 
* 
*  Now, see if there is a data (record) buffer already allocated.  If so, 
*  see if it is large enough for this data base.  If so, we are done, re- 
*  turn to the user.  If not, deallocate the current buffer (if one) and
*  try to allocated a new one.  If this words, we are once again finished.
*  If not, we need to undo everything and return unsuccessful to the user.
* 
      LDB DBRBL     DBRBL = length of allocated data buffer.
      STB SAVE
      SZB,RSS       If its zero,
      JMP ROPN4       branch around deallocation. 
* 
      CMB 
      ADB CNTR      If its >= size we need, 
      SSB 
      JMP ROPN6       successful open.
* 
      JSB RETBF     Else, deallocate it.
       DEF *+2
       DEF DBRBP
* 
      LDB D160      If any error, 
      SSA             someone's walked on our memory. 
      JMP RCLN1 
* 
      CLA 
      STA DBRBL 
* 
ROPN4 JSB GETBF     Try to allocate new buffer. 
       DEF *+4
       DEF CNTR 
       DEF DBRBP
       DEF ERROR
* 
      LDB D128
      SSA           If any error, 
      JMP RCLNP       then return proper error code.
* 
ROPN5 LDB CNTR      Else set buffer size to 
      STB DBRBL       size of new buffer. 
* 
*  All went well, put the data base number in the ibase parameter and re- 
*  turn to the user.
* 
ROPN6 LDB DBNUM 
      STB BASE,I
* 
ROPN7 JMP RBOPN,I 
* 
*  Error return points. 
* 
E103  LDB D103      Illegal base parameter. 
      RSS 
E115  LDB D115      Illegal open mode.
      RSS 
E128  LDB D128      Not enough memory.
      RSS 
E150  LDB D150      Data base already open error
      RSS 
E160  LDB D160      Bad memory error. 
* 
ROPN8 STB STAT,I
      JMP ROPN7 
      SKP 
* 
*  The following is the cleanup routine for RBOPN.  There are three dif-
*  ferent entry points.  These are: 1) RCLNP - record buffer has possibly 
*  been altered.  2) RCLN1 - the remote DBOPN has succeeded.  3) RCLN3 -
*  the Run Table has been allocated.  Each entry point presupposes the
*  cleanup for the next.  When entered at RCLNP or RCLN1, the B register
*  has the proper error code. 
* 
*  RCLNP is the first entry point.  Put error code in status array.  Then 
*  compare SAVE and DBRBL to see if data (record) buffer has been altered.
* 
RCLNP STB STAT,I
* 
      LDB DBRBL     Are new and old 
      CPB SAVE        lengths the same? 
      JMP CLN11       Yes - no cleanup needed.
* 
      SZB,RSS         No - is new length = 0? 
      JMP CLNP1         Yes - no deallocation.
* 
      JSB RETBF         No - deallocate new buffer. 
       DEF *+2
       DEF DBRBP      Ignore any errors.
* 
CLNP1 LDB SAVE      Is old record buffer
      SZB,RSS         size = zero?
      JMP CLNP2       Yes - no allocation.
* 
      JSB GETBF       No - allocate the same
       DEF *+4          size data buffer. 
       DEF SAVE 
       DEF DBRBP
       DEF ERROR
* 
      CLB           If any error, 
      SSA,RSS         set buffer size to zero 
      LDB SAVE        else set to old size
CLNP2 STB DBRBL 
      JMP CLN11 
* 
*  RCLN1 is the second entry point.  Put error code in status array.
* 
*  Update AIRUN in case a RETBF, GETBF sequence altered the location
*  of the Run Table.  Then, send a remote DBCLS request.
* 
RCLN1 STB STAT,I
* 
CLN11 LDA RTPTR,I 
      STA AIRUN 
* 
      JSB RBMST 
       DEF *+11 
       DEF D38      RBMST needs: RDBA Index 
       DEF D1                    close mode 
       DEF D0                    data set number
       DEF D0                    dummy
       DEF BASE,I                data base parameter
       DEF NAME                  status array 
       DEF D0                    outgoing data buffer 
       DEF D0                    outgoing data length 
       DEF NAME                  incoming data buffer 
       DEF D0                    incoming data length 
      NOP           error return point
* 
*  RCLN2 is the third entry point.  Error code is already in status array.
*  All there is left to do is deallocate the Run Table space. 
* 
RCLN2 JSB RETBF 
       DEF *+2
       DEF RTPTR,I
* 
      JMP ROPN7 
      SKP 
* 
*  Constants and variables. 
* 
D0    EQU ZERO
D1    EQU ZERO+1
D2    EQU ZERO+2
D3    EQU ZERO+3
D4    EQU ZERO+4
D5    EQU ZERO+5
D7    EQU ZERO+7
D8    EQU ZERO+8
D36   DEC 36
D38   DEC 38
D100  DEC 100 
D103  DEC 103 
D115  DEC 115 
D127  DEC 127 
D128  DEC 128 
D150  DEC 150 
D160  DEC 160 
D1899 DEC 1899
* 
BLNKS ASC 1,
* 
ADDRS NOP 
NAME  BSS 3         } NOTE:  Do not change the order
CNTR  NOP           }   is the 10 word array for
CRN   NOP           }   DBPAR call. 
DBNUM NOP           } 
ERROR NOP           } 
TEMP  NOP           } 
SAVE  NOP           } 
MAXRT NOP           } 
* 
FLAG  NOP 
RTPTR NOP 
INDA  NOP 
      END 
                                                                                                        