ASMB
      HED RDBAM - REMOTE DATA BASE ACCESS MONITOR 
      NAM RDBAM,148,30 91750-16024 REV.2013 800523
* 
* 
******************************************************************* 
* (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:    91750-18024
*     RELOC:     91750-16024
* 
* 
* 
******************************************************************* 
* 
* 
* 
*  RDBAM is the Remote Data Base Access Monitor.  It performs the following 
*  sequence of operations:
* 
*  1)  When first scheduled (by LSTEN or UPLIN) get class number from first 
*      parameter, and store in the
*      program's memory space.  The second scheduling parameter is the
*      error LU (first time through). Set it to 1.
* 
*  2)  Make sure the Remote Data Base Access Program (RDBAP) resides in 
*      the system.  If not, send a message to the log device. 
* 
*  3)  Check the RDBAP table to see if any RDBAP copies were previously 
*      scheduled.  If so, for each copy of RDBAP scheduled, if copy is
*      not up, release its class, remove its entry from the table, and
*      remove the copy from the system. 
* 
*  4)  Do a class GET on the class from 1 to await a Remote Data Base Access
*      (RDBA) request.
* 
*  5)  When a request is received, make sure the request buffer is no larger
*      than our maximum buffer size (now 30 words).  If a zero length re- 
*      quest, flush it from the class and return to 4.  If request size okay
*      bring it into the program memory.
* 
*  6)  If RDBA Index of request a -1 (negative one), this is a special
*      clean-up request from the DS software.  The RDBA mode word contains
*      either the first two characters of the master program's name or a
*      negative integer.
* 
*      A)  If the mode word contains a positive value (two characters): 
* 
*          I  )  Look for master's entry in RDBAP copy scheduling table.
*                If found, then if RDBAP copy still up, reroute the mes-
*                sage to it and return to 4.
* 
*          II )  If entry found but RDBAP copy is in a bad state, remove
*                the copy from the system, release its class number, and
*                remove its entry from the scheduling table.
* 
*          III)  Flush request from our class (through PLOG if enabled) 
*                and send a successful reply to requestor.
* 
*          IV )  Return to 4. 
* 
*      B)  Mode word contains a negative number.  For each RDBAP copy 
*          scheduled: 
* 
*          I  )  If copy dormant or on its class get, abort it and remove 
*                it from the system.
* 
*          II )  Release the copy's class number and remove it from the 
*                scheduling table.
* 
*          III)  Go to 5-A-III. 
* 
*  7)  If RDBA Index of request is a -2 (negative two), this is a "remove 
*      me, I'm done" request from an RDBAP copy.  The RDBA mode word con- 
*      tains the copy's index into the RDBAP copy scheduling table.  Deter- 
*      mine the copy's entry in the scheduling table using this index.
*      Remove the copy from the system, release its class and remove it 
*      from the scheduling table.  Flush the request from our class and 
*      return to 4. 
* 
*  8)  All other Indices are RDBA requests.  Get the RDBA index and bound 
*      bound check it.  (Each IMAGE call has its own Index, for instance
*      DBOPN's Index is 36.)
* 
*  9)  If Index is not within bounds, flush request from class (through 
*      PLOG if enabled) and send a reply with the proper DS error code, 
*      then go to 4.
* 
* 10)  If the Index is 36 (i.e. DBOPN call) then: 
* 
*      A)  See if there is an RDBAP copy scheduled for this master.  If 
*          so, go to 11.
* 
*      B)  If no copy scheduled, then get next free entry in RDBAP copy 
*          scheduling table.  If no free entry, flush request from class
*          (through PLOG if enabled), send a reply with the proper DS 
*          error code, then return to 4.
* 
*      C)  Ask C.RP to bring up a new copy of RDBAP suffixing the copy
*          with the ASCII equivalent of the copy's index into the schedul-
*          ing table plus one.  If C.RP is unsuccessful, flush the request
*          from our class (through PLOG if enabled), send a reply with
*          the proper DS error code, then return to 4.
* 
*      D)  Allocate a class for this copy of RDBAP.  If any error, remove 
*          RDBAP copy from system, flush the request from our class (through
*          PLOG if enabled), send a reply with the proper DS error code,
*          then return to 4.
* 
*      E)  Schedule the RDBAP copy sending it its class, its index, and 
*          our class.  If unsuccessful, remove the RDBAP copy from the
*          system, release its class, remove its scheduling table entry,
*          flush the request from our class (through PLOG if enabled),
*          send a reply with the proper DS error code, then return to 4.
* 
*      F)  Go to 12.
* 
* 10)  If the RDBA Index is not 36, the index into the scheduling table 
*      for this master's copy of RDBAP is in the request buffer.  Pick
*      it up and determine the address of the copy's entry in the table 
*      with it. 
* 
* 11)  Make sure the RDBAP copy is still up.  If not, remove it from the
*      system, release its class number, remove it from the scheduling
*      table, flush the request from our class (through PLOG if enabled)
*      send a reply with the proper DS error code, then return to 4.
* 
* 12)  Transfer the request from our class to the RDBAP copy's class. 
* 
* 13)  Go to 4. 
* 
      SKP 
**********************************************************************
***                                                                ***
*                  Standard DS/1000 equates                          *
***                                                                ***
*$
* 
******************************************************************
*                                                                *
*     G L O B A L   B L O C K               REV XXXX 790531      *
*                                                                *
*     GLOBAL OFFSETS INTO DS/1000 MESSAGE BUFFERS, USED BY:      *
*                                                                *
*         REMAT, RFMST, DEXEC, DMESS, FLOAD, POPEN, #MAST        *
*         GET,   #SLAV, RQCNV, RPCNV, GRPM,  LSTEN, PTOPM        *
*         EXECM, EXECW, OPERM, RFAM1, RFAM2, DLIST, DLIS3        *
*                                                                *
******************************************************************
* 
***!!!!! THE FIRST 7 WORDS (#STR THRU #ENO) MUST BE FIXED !!!!!***
#STR  EQU 0         STREAM WORD.
#SEQ  EQU #STR+1    SEQUENCE NUMBER.
#SRC  EQU #SEQ+1    SOURCE NODE #.
#DST  EQU #SRC+1    DEST. NODE #. 
#EC1  EQU #DST+1    REPLY ECOD1.
#EC2  EQU #EC1+1    REPLY ECOD2.
#ENO  EQU #EC2+1    NUMBER OF NODE REPORTING ERROR. 
* 
#ECQ  EQU #ENO+1    ERROR CODE QUALIFIER (BITS 4 TO 7)
#LVL  EQU #ECQ      MESSAGE FORMAT LEVEL (BITS 0 TO 3)
#MAS  EQU #LVL+1    MA "SEND" SEQ. #
#MAR  EQU #MAS+1    MA "RECV" SEQ. #
#MAC  EQU #MAR+1    MA "CANCEL" FLAGS 
#HCT  EQU #MAC+1    HOP COUNT 
#SID  EQU #HCT+1    SESSION ID WORD 
* 
#EHD  EQU #SID      LAST ITEM OF HEADER 
#MHD  EQU #EHD+1    MINIMUM HEADER SIZE 
#REQ  EQU #MHD      START OF REQUEST SPECIFIC AREA
#REP  EQU #MHD      START OF REPLY SPECIFIC AREA
* 
#MXR  EQU #MHD+24   <<< MAXIMUM DS REQ/REPLY BUFFER SIZE >>>
#LSZ  EQU 2         <<< SIZE OF LOCAL APPENDAGE AREA >>>
* 
******************************************************************
* 
*$
***                                                                ***
**********************************************************************
RQBUF BSS 30
**********************************************************************
*                                                                    *
*  DS/1000 RDBA Communications consist of two descriptive buffers:   *
*          1) Request buffer                                         *
*          2) Reply buffer                                           *
*  These two static buffers are as described below.                  *
*                                                                    *
**********************************************************************
***                                                                ***
*                                                                    *
*  Request buffer - one buffer of from 12 to 21 words per RDBA call  *
*                                                                    *
***                                                                ***
RBSTR EQU RQBUF+#STR     DS/1000 stream word
RBSEQ EQU RQBUF+#SEQ     DS/1000 sequence number
RBSRC EQU RQBUF+#SRC     DS/1000 source node number 
RBDST EQU RQBUF+#DST     DS/1000 destination node number
RBIDX EQU RQBUF+#REQ     RDBA call Index
RBMOD EQU RQBUF+#REQ+1   RDBA call mode 
RBID  EQU RQBUF+#REQ+2   RDBA call item or set number 
*                                    or for a DBOPN, the level code word
RBITM EQU RQBUF+#REQ+3   Search item number for DBFND 
RBMRT EQU RQBUF+#REQ+5   For DBOPN, the max. return RT size 
RBLEN EQU RQBUF+#REQ+6   Word size of ibase parameter 
RBBAS EQU RQBUF+#REQ+7   Ibase parameter
* 
MAXRQ DEC 30        Maximum request buffer length 
***                                                                ***
***                                                                ***
*                                                                    *
*  Reply buffer - one buffer of 13 words per RDBA call (standard re-  * 
*    ply header only sent back by RDBAM upon an error).              *
*                                                                    *
***                                                                  *
* RBSTR EQU RQBUF+#STR   DS 1000 stream word
* RBSEQ EQU RQBUF+#SEQ   DS/1000 sequence number
* RBSRC EQU RQBUF+#SRC   DS/1000 source node number 
* RBDST EQU RQBUF+#DST   DS/1000 destination node number
RBEC1 EQU RQBUF+#EC1     DS/1000 1st error code word
RBEC2 EQU RQBUF+#EC2     DS/1000 2nd error code word
RBEC3 EQU RQBUF+#ENO     DS/1000 error node number upon an error
* 
RPLEN DEC 13        Standard reply header length
***                                                                ***
**********************************************************************
      SKP 
**********************************************************************
*                                                                    *
*  RDBAP copy scheduling table                                       *
*  The scheduling table resides in the module RD.TB in SSGA.  It     *
*  consists of information necessary for the co-ordination of RDBAP  *
*  copy scheduling and request routing.  Further detail follows.     *
*                                                                    *
**********************************************************************
***                                                                ***
*                                                                    *
*  RDBAP copy scheduling table - one 8 word entry per RDBAP copy     *
*                                                                    *
***                                                                ***
BPSIZ DEC 8         Entry size
* 
BPID# DEC 0         Master program's name - 3 words 
BPNOD DEC 3         Master's node number
BPNAM DEC 4         Name of RDBAP copy - 3 words
BPCLS DEC 7         Class number for RDBAP copy 
***                                                                ***
***                                                                ***
*                                                                    *
*  The first two words in this subroutine contain:                   *
*          1)  the number of copies of RDBAP currently scheduled     *
*          2)  the number of entries in the scheduling table         *
*                                                                    *
*  The scheduling table starts in the third word of the module.      *
*                                                                    *
***                                                                ***
* 
* 
      ENT RDBAM 
      EXT #PLOG,#RQUE,.CMW,#GETR,#LOGR,DTACH
      EXT .ENTR,.MVW,C.RP,EXEC,RD.TB,RDEXT,RMPAR
* 
A     EQU 0 
B     EQU 1 
* 
*  Get our class number and set its save buffer, no deallocate bits.
*  Then set the error lu to 1.
* 
RDBAM NOP 
      JSB RMPAR 
       DEF *+2
       DEF CLASS
* 
* Detach from a session. If RDBAM was loaded under a session, it will 
* belong to that session. 
* 
      JSB DTACH 
      DEF *+1 
* 
*  Set the error LU to the console LU1. 
* 
      CLA,INA 
      STA ERLU
* 
*  Ask C.RP to check to make sure that RDBAP is there.
* 
      LDB RDBAP 
      CLA,INA 
      JSB C.RP
      JSB BAPER     Not there, warn user. 
* 
*  If C.RP had to duplicate the ID, ask it to undo the find.  The A regi- 
*  ster will be non-zero in this case.
* 
      SZA,RSS 
      JMP CHK0
      LDB RDBAP 
      CLA 
      JSB C.RP
      NOP           Ignore errors.
* 
*  See if we are being rescheduled after having been aborted.  If so, the 
*  count of RDBAP copies in use may be non-zero, and the states of these
*  copies should be checked.
* 
CHK0  LDA RD.TB     Entry point in SSGA is RD.TB
      LDB A,I 
      SZB,RSS 
      JMP GET       No copies scheduled.
* 
*  For each copy of RDBAP scheduled, make sure it is still up, i.e. it is 
*  non-dormant.  This is done by trying to schedule it without wait.  If
*  the schedule works or aborts, the copy is dormant and should be removed
*  from the scheduling table. 
* 
      CMB,INB       Two loop counters:
      STB CNTR1     1) -(# of copies scheduled) 
      INA 
      LDB A,I       2) -(# of entries in table) 
      SZB,RSS       # of entries = 0? 
      JMP GET         Nothing we can do about it. 
      CMB,INB 
      STB CNTR2 
* 
      INA           A -> scheduling table.
      CLB,INB       Set index in scheduling 
      STB INDEX       table to one. 
* 
CHK1  STA ENTAD 
      LDB A,I       If the entry is not empty,
      SZB,RSS 
      JMP CHK4
      JSB SCHED       SCHED will schedule it
       DEF *+1        for us. 
      JMP CHK2      Schedule aborted. 
* 
      AND LOFOR     Low four bits of A reg. = 
      SZA             status of copy at schedule. 
      JMP CHK3      If zero, copy was dormant 
* 
CHK2  JSB TERM        terminate it
      JSB RID         and remove it from table. 
* 
CHK3  ISZ CNTR1     Done with all scheduled copies? 
      RSS 
      JMP GET         Yes - go to class get.
* 
CHK4  ISZ INDEX     Update index into table 
      LDA ENTAD     Get next entry's address
      ADA BPSIZ 
      ISZ CNTR2       and continue for all
      JMP CHK1        entries in table. 
* 
*  Do a class GET on our passed class to await an RDBA request.  The get
*  allows abort since an abort indicates our class number is incorrect
*  and after aborting, UPLIN will bring us back with the correct class
*  number, hopefully.  If UPLIN cannot bring us back something is dras- 
*  tically wrong anyway.
* 
*  If this is a zero-length request, then just flush it from the system.
*  Else, check the length of the request to make sure it is within the
*  upper bound of an RDBA request buffer
* 
* 
*  The request length is okay.  Move the request from system memory into
*  our own buffer.
* 
* 
*  Set the clean-up flag to FALSE 
* 
GET   CLA 
      STA FLAG
* 
* 
* 
      JSB #GETR 
       DEF *+6
       DEF CLASS
       DEF RQBUF
       DEF MAXRQ
       DEF MNAME,I
       DEF D3 
      JMP CLERR    Error return, class must be bad
* 
*  Save the request buffer length and the data buffer length
* 
      STA RQLEN 
      STB DALEN 
      SKP 
* 
*  Check to see if this is a special clean-up request from the DS software. 
*  The RDBA Index for such a request is -1 (negative one).
* 
      LDA RBIDX 
      INA,SZA 
      JMP RDBA7     Not a clean-up request. 
* 
*  This is a clean-up request, get the master's name and node # from
*  the request (next four words after Index).  If the first word of the name
*  is > zero, get its associated RDBAP copy's entry in the RDBAP table.  If 
*  the copy is up and running, send it a clean-up request, else do the
*  clean-up for it. 
* 
*  If the first word of the name is < zero, this is a shut down clean-up, 
*  abort all RDBAP copies.
* 
      LDA RBMOD 
      SSA 
      JMP CLNA      Shut down clean-up. 
* 
*  Single copy clean-up.  Get the copy's entry in the scheduling table. 
* 
      JSB SERCH 
       DEF *+3
       DEF RBMOD
       DEF RBMOD+3
      JMP CLN3      No entry for it found.
      RSS           Entry found 
      JMP CLN3      No entry for it found.
* 
*  Copy for master found, see if it is dormant by scheduling it.  If it 
*  is dormant the schedule should either abort or succeed.
* 
      JSB SCHED 
       DEF *+1
      JMP CLN2      Schedule aborted. 
* 
      AND LOFOR     Check schedule state. 
      CMA,INA       If state is 1, 2, or 3
      INA,SZA,RSS 
      JMP CLN1        copy is still up. 
      INA,SZA,RSS 
      JMP CLN1
      INA,SZA 
      JMP CLN2
* 
*  Copy is still there, ask SWTCH to switch the clean-up message from our 
*  class to its.
* 
CLN1  JSB SWTCH 
      RSS           Error return, clean-up the copy ourselves.
      JMP GET       Return to class get.
* 
*  Copy was dormant, ask TERM to get rid of it and RID to remove it from
*  the scheduling table.
* 
CLN2  ISZ FLAG     Set the get-rid-of-RDBAP flag
CLN3  CLB            Clear the error word 
      JMP EREXT 
* 
*  Constants and variables. 
* 
RQADR NOP 
RQLEN NOP 
D21   DEC 21
* 
      SKP 
* 
*  Clean up all RDBAP copies request.  Set up a loop to check each entry in 
*  the RDBAP copy scheduling table for a scheduled copy.  If there is one 
*  in it, see if it is executing (i.e. non-dormant or not on its class get).
*  If so, just release its class and remove its entry in the scheduling 
*  table.  If not, remove it from system, and then release its class and
*  entry. 
* 
CLNA  LDA RD.TB     Two loop counters.
      LDB A,I       1) -(# of copies scheduled) 
      SZB,RSS         If no copies scheduled, 
      JMP CLN3        just send reply.
      CMB,INB 
      STB CNTR1 
      INA 
      LDB A,I       2) -(# entries in table)
      SZB,RSS       # of entries = 0? 
      JMP CLN3        Yes - just send reply.
      CMB,INB 
      STB CNTR2 
* 
      CLB,INB       Set index into table to 1.
      STB INDEX 
      INA           Get table address.
* 
CLNA1 STA ENTAD 
      LDB A,I       Entry empty?
      SZB,RSS 
      JMP CLNA4       Yes 
* 
      JSB SCHED       No - executing? 
       DEF *+1
      JMP CLNA2         No - not there! 
* 
      AND LOFOR 
      SZA,RSS           Dormant,
      JMP CLNA2 
      CPA D3            or on its class get?
      RSS 
      JMP CLNA3           No, (it aborts on next class get) 
* 
CLNA2 JSB TERM      Terminate the copy. 
CLNA3 JSB RID       Remove it from the table. 
* 
      ISZ CNTR1     Done with all scheduled copies? 
      RSS 
      JMP CLN3        Yes - send reply. 
* 
CLNA4 ISZ INDEX     Bump index
      LDA ENTAD       get next entry
      ADA BPSIZ 
      ISZ CNTR2       and continue for
      JMP CLNA1       entries in table. 
      JMP CLN3      Then, go send reply.
      SKP 
* 
*  Check to see if this is a special "remove me" request from an RDBAP copy.
*  The RDBA Index for such a request is -2.  The A register at this point 
*  contains the RDBA Index plus 1, therefore, if the A register is -1 now,
*  this is a "remove me" request. 
* 
RDBA7 INA,SZA 
      JMP RDBA8     No - a valid RDBA request.
* 
*  Get index into RDBAP copy table from the 6th word of the request.  This
*  gives us the address of the copy's entry in the scheduling table by: 
*     ((Index - 1) * length of entry) + address of scheduling table.
* 
      CCA 
      ADA RBMOD 
      CLB 
      MPY BPSIZ 
      LDB RD.TB 
      ADB D2
      ADA B 
      STA ENTAD 
* 
*  Ask TERM to remove the RDBAP copy from the system, and RID to remove its 
*  entry in the scheduling table.  Then, remove the request from our class
*  and return to the class get. 
* 
      ISZ FLAG
      JMP OFFIT 
      SKP 
* 
*  This is a valid RDBA request.  Our first action is to bound check the
*  RDBA Index (5th word of the request buffer).  The Index must be within 
*  [36..45].
* 
RDBA8 LDA RBIDX 
      CMA,INA 
      ADA D45       Is the index < 46?
      SSA 
      JMP IDXER       No - index error. 
* 
      ADA M10         Yes - is it > 35? 
      SSA,RSS 
      JMP IDXER         No - index error. 
* 
*  Now, check the Index for a DBOPN call.  The Index for DBOPN is 36, but 
*  by the bounds check done above, 36 has been mapped into a -1.
* 
      INA,SZA 
      JMP NOTOP 
* 
*  This is a DBOPN request, we need to check for an RDBAP copy already
*  scheduled for this master.  While checking, we also need to get the
*  index for the first free entry in the RDBAP copy table in the event
*  this is the first request from the master.  The master program's name
*  is the data received with the request buffer.  Ask SERCH to do the 
*  check for us.
* 
      JSB SERCH 
       DEF *+3
       DEF MNAME,I
       DEF RBSRC
      JMP BUERR     No RDBAP copy up and no room! 
      JMP RDBA9     RDBAP copy up.
* 
*  There is no current copy of RDBAP for this master, get one for it. 
* 
      LDB RDBAP 
      LDA EMPTY 
      INA 
      JSB C.RP
      JMP BUERR     Did not work! 
* 
*  Build the entry for the master-copy pair.
* 
      STB TEMP      Save pointer to copy's name for later.
      LDA EMPTY 
      STA INDEX     Save its index for later. 
* 
      ISZ RD.TB,I   Bump copy count.
* 
      ADA M1
      CLB 
      MPY BPSIZ     Get the address of the entry
      LDB RD.TB       for this copy (derived from index). 
      ADB D2
      ADA B 
      STA ENTAD 
* 
      STA B         1st - 3rd words:
      LDA MNAME       master's name.
      JSB .MVW
       DEF D3 
       DEC 0
* 
      LDA RBSRC     4th word: 
      STA B,I         master's node number. 
* 
      INB           5th - 7th words:
      LDA TEMP        copy's name 
      JSB .MVW
       DEF D3 
       DEC 0
* 
      LDA CLSWD     8th word: 
      STA B,I         class number, 
      STB CLSAD       allocated one.
      JSB EXEC
       DEF *+5
       DEF NA19     Class control, no abort 
       DEF D0       LU = 0
       DEF D0 
CLSAD  ABS *-*
      JMP CLERR     Abortion return!
* 
      LDA CLSAD,I   Did we get a class? 
      AND MAPHI 
      SZA,RSS 
      JMP CLERR       NO! 
* 
      IOR BIT13       Yes - reset nodeallocate bit
      STA CLSAD,I     and do a class get to 
      JSB EXEC        remove class control
       DEF *+5        buffer from class.
       DEF NA21 
       DEF CLSAD,I
       DEF DUMMY
       DEF D0 
      JMP CLERR     Abortion return.
* 
*  Schedule the RDBAP copy, then join with non-open processing to pass it 
*  the reqeust. 
* 
      ISZ FLAG       Set the get-rid-of-RDBAP flag
* 
      JSB SCHED 
       DEF *+1
      JMP BUERR     Schedule did not work!  Go to busy error exit.
      JMP JOIN
* 
*  Constants and variables. 
* 
M10   DEC -10 
D45   DEC 45
CLSWD OCT 160000
* 
MNAME DEF *+1 
      BSS 3 
* 
RDBAP DEF *+1 
      ASC 3,RDBAP 
      SKP 
* 
*  We come here if the request was not a DBOPN.  We assume that a monitor 
*  already exists for the request and that the index for its entry in the 
*  RDBAP copy scheduling table is in the high order byte of the 12th word 
*  of the request buffer.  We get the index from the buffer and calculate 
*  the entry's address from it by : 
*      ((Index - 1) * length of entry) + address of copy table. 
* 
NOTOP LDA RBBAS 
      ALF,ALF 
      AND LOBYT 
      STA INDEX 
      ADA M1
      CLB 
      MPY BPSIZ 
      LDB RD.TB 
      ADB D2
      ADA B 
      STA ENTAD 
* 
*  Make sure the copy is still there by trying to schedule it.  If the
*  schedule aborts or succeeds, we need to clean up after the copy and
*  send the master a schedule error.
* 
RDBA9 JSB SCHED 
       DEF *+1
      JMP BAM2      Abortion return.
* 
      AND LOFOR     If low four bits of A = zero, 
      SZA             RDBAP copy was dormant. 
      JMP JOIN
* 
BAM2  ISZ FLAG      Get copy out of system, remove it's table entry 
      JMP SCERR       and send master an error reply. 
* 
*  All went well.  Transfer the request from RDBAM's class to the RDBAP 
*  copy's class.  Then, return to the class get.
* 
JOIN  JSB SWTCH 
      RSS           Error return
      JMP GET       Normal return 
      CPA M10       If too many requests error, 
      JMP BUERR       send a busy error 
      JMP CLER2       else send a class error.
* 
*  Constants and variables. 
* 
LOFOR OCT 17
LOBYT OCT 377 
DALEN NOP 
* 
      SKP 
* 
*  Error handlers.
* 
SIZER LDB M153      Illegal request length
      JMP EREXT 
* 
IDXER LDB M159      Illegal Index parameter.
      JMP EREXT 
* 
CLERR ISZ FLAG      No class available
CLER2 LDB M158        or class errror from #REQU. 
      JMP EREXT 
* 
SCERR LDB M144      RDBAP copy not up.
      JMP EREXT 
* 
BUERR LDB M156      System is too busy error. 
* 
EREXT CLA           Set the error code for the reply. 
      DST ERROR 
* 
      LDB #PLOG     Flush the request from our class.  If 
      SZB,RSS         PLOG is enabled, give 
      JMP ZREQ        the request to it 
* 
      JSB #LOGR 
      JMP EXT3      Error exit
* 
ZREQ  LDA RQLEN     If this was a zero-length 
      SZA,RSS         request, just return to 
      JMP OFFIT       class GET.
* 
EXT3  JSB RDEXT     Else, send reply with 
       DEF *+6        DS error code to orginator. 
       DEF RQBUF
       DEF RPLEN
       DEF DUMMY
       DEF D0       no data 
       DEF ERROR    two word error code 
      NOP           ignore any errors.
* 
*  Remove class buffer from our class 
* 
OFFIT JSB RMOVE 
* 
* 
      LDA FLAG      Any more clean-up to do?
      SZA,RSS 
      JMP GET         No - return to class get. 
* 
      JSB TERM        Yes - get rid of new
      JSB RID           copy of RDBAP.
      JMP GET         Then return to class get. 
* 
*  Constants and variables. 
* 
M159  DEC -159
M158  DEC -158
M156  DEC -156
M153  DEC -153
D0    EQU BPID# 
* 
NA21  OCT 100025
* 
DUMMY NOP 
ERROR BSS 2 
CLAS2 NOP 
CLASS BSS 5 
ERLU  EQU CLASS+1 
FLAG  NOP 
      SKP 
* 
*  SERCH is a utility subroutine for RDBAM which searches the RDBAP copy
*  scheduling table for a copy of RDBAP associated with the master whose
*  name is the same as that passed and for the first empty entry in the 
*  table, leaving its index in EMPTY. 
* 
*  The calling sequence for SERCH is: 
* 
*         JSB SERCH 
*          DEF *+3        return address
*          DEF IDSNM      master program's name 
*          DEF SRCND      master program's node number
*        <error return: no entry found for master and no empty entry exists>
*        <entry found for master return: ENTAD = address or its entry 
*                                        INDEX = its index> 
*        <master's entry not found, but an empty entry was return:
*                                        EMPTY = index for empty entry> 
* 
IDSNM NOP 
SRCND NOP 
SERCH NOP 
      JSB .ENTR 
       DEF IDSNM
* 
*  Set up parameters for table search.
* 
      LDA RD.TB     Two loop counters:
      LDB A,I       1) -(# of copies scheduled) 
      CMB,INB 
      STB CNTR1 
      INA 
      LDB A,I       2) -(# of entries in table) 
      SZB,RSS       If # of entries = 0,
      JMP SRCH7       take error return.
      CMB,INB 
      STB CNTR2 
* 
      INA           A -> RDBAP copy scheduling table
      CLB 
      STB EMPTY     EMPTY = ENTAD = 0 
      STB ENTAD 
      INB           First index into table is one.
      STB INDEX 
* 
*  BEGIN MAJOR LOOP 
* 
*    BEGIN MINOR LOOP 
* 
SRCH0 STA TABAD 
      LDB A,I       If the entry is not empty,
      SZB,RSS 
      JMP SRCH3 
      LDB IDSNM       compare the master names. 
      JSB .CMW
       DEF D3 
       DEC 0
      JMP SRCH1     A match 
      NOP 
      JMP SRCH2     Not a match 
* 
SRCH1 LDB A,I       A match, compare node numbers.
      CPB SRCND,I 
      RSS           A match, entry found. 
      JMP SRCH4     Not a match, try next 
* 
      LDA TABAD     Set up ENTAD for return 
      STA ENTAD       and return P+2. 
      JMP SRCH6 
* 
SRCH2 ISZ CNTR1     Not a match, done with all scheduled copies?
      JMP SRCH4       No
      LDA EMPTY       Yes - did we already find 
      SZA               an empty entry? 
      JMP SRCH5         Yes 
      JMP SRCH4         No
* 
*    END MINOR LOOP 
* 
SRCH3 LDB INDEX     Empty entry found,
      LDA EMPTY       first one?
      SZA,RSS 
      STB EMPTY       Yes - save its index. 
* 
SRCH4 LDA TABAD     Get next entry's address
      ADA BPSIZ 
      ISZ INDEX       bump index
      ISZ CNTR2       and try next one. 
      JMP SRCH0 
* 
*  END MAJOR LOOP 
* 
*  Here when entire table is searched.
* 
      LDA EMPTY     Did we find an empty entry? 
      SZA,RSS 
      JMP SRCH7       No
SRCH5 ISZ SERCH       Yes return P+3. 
SRCH6 ISZ SERCH     Entry found, return P+2.
SRCH7 JMP SERCH,I   Return. 
      SKP 
* 
*  RID is a utility subroutine for RDBAM which remove an RDBAP copy from
*  the scheduling table by releasing its class number and zeroing the 
*  first word of its entry. 
* 
*  The calling sequence for RID is: 
* 
*         ENTAD = address of RDBAP copy's entry in scheduling table to
*                 get rid of. 
*         JSB RID 
*        <return point> 
* 
RID   NOP 
* 
*  Get the RDBAP copy's class number, clear its save buffer bit and set 
*  its save class and no wait bits. 
* 
      LDB ENTAD 
      ADB BPCLS 
      LDA B,I 
      CCE,SZA,RSS   If class never allocated, 
      JMP RID3        just clear entry. 
      AND MAPHI 
      IOR BIT13 
      RAL,ERA 
      STA CLAS2 
* 
*  Set up a loop to remove all requests on this class number, then to re- 
*  lease the class number.
* 
RID1  CCA           Set the release retry 
      STA TEMP        switch to -1. 
* 
RID2  JSB EXEC      Go to RTE to release class buffer.
       DEF *+5
       DEF NA21     Class get, no abort 
       DEF CLAS2
       DEF DUMMY
       DEF D0 
      RSS           Ignore errors.
* 
      ISZ TEMP      Release processing completed? 
      JMP RID3        Yes - zero entry. 
      INA,SZA         No - all pending reqs. cleared? 
      JMP RID1          No - continue to clear requests.
* 
      LDA CLAS2         Yes - remove save class 
      XOR BIT13           number bit (bit 13) 
      STA CLAS2           and return for final
      JMP RID2            deallocation. 
* 
*  Set the first word of the entry to zero to signify the entry is empty, 
*  decrement the copy count, then return. 
* 
RID3  CLA 
      STA ENTAD,I 
      CMA 
      ADA RD.TB,I 
      STA RD.TB,I 
      JMP RID,I 
      SKP 
* 
*  SCHEDule is a utility subroutine for RDBAM which schedules the RDBAP 
*  copy described in the entry of the RDBAP copy scheduling table speci-
*  fied in ENTAD.  The schedule is immediate, without wait and the RDBAP
*  copy is passed:
*           1)  its class number
*           2)  its index into the scheduling table 
*           3)  RDBAM's class number
* 
*  The calling sequence for SCHED is: 
* 
*        ENTAD = address of RDBAP copy's entry in scheduling table
*        INDEX = index into scheduling table for RDBAP copy's entry 
*        JSB SCHED
*         DEF *+1       return address
*       <abortion return> 
*       <normal return: A register contains status of RDBAP copy> 
* 
SCHED NOP 
      JSB .ENTR 
       DEF SCHED
* 
*  Get addresses of RDBAP copy's name and class number in entry, and put
*  them into scheduling EXEC call.
* 
      LDA ENTAD 
      ADA BPNAM 
      STA NAMAD 
      ADA D3
      STA CLADR 
* 
*  Schedule RDBAP copy. 
* 
      JSB EXEC
       DEF *+6
       DEF NA10     Immediate schedule, no wait, no abort 
NAMAD  ABS *-*
CLADR  ABS *-*
       DEF INDEX
       DEF CLASS
      JMP SCHED,I   Abortion return point.
* 
      ISZ SCHED 
      JMP SCHED,I   Normal return point.
      SKP 
* 
*  TERMinate is a utility subroutine for RDBAM which terminates the copy
*  of RDBAP specified by the entry in the scheduling table pointed to by
*  ENTAD and removes it from the system.
* 
*  The calling sequence for TERM is:
* 
*         ENTAD = address of RDBAP copy's entry in scheduling table 
*         JSB TERM
*        <return point> 
* 
TERM  NOP 
* 
*  Get address of RDBAP copy's name and put it in terminating EXEC call.
* 
      LDA ENTAD 
      ADA BPNAM 
      STA OFNAM 
* 
*  Go to RTE to terminate the copy normally.
* 
      JSB EXEC
       DEF *+4
       DEF NA6      Terminate, no abort.
OFNAM  ABS *-*
       DEF D0       Normal completion.
      NOP           Ignore errors.
* 
*  Ask C.RP to remove the copy's ID segment from the system.
* 
      LDB OFNAM 
      CLA 
      JSB C.RP
      NOP           Ignore errors.
      JMP TERM,I    Return to caller. 
* 
* 
NA6   OCT 100006
      SKP 
* 
*  SWTCH is a utility subroutine for RDBAM which calls #RQUE to transfer
*  a request from RDBAM's class to the class of the RDBAP copy specified
*  by the entry of the scheduling table pointed to by ENTAD.
* 
*  The calling sequence for SWTCH is: 
* 
*         ENTAD = address of entry in scheduling table for RDBAP copy 
*         JSB SWTCH 
*        <error return point, A = error code> 
*        <normal return point>
* 
SWTCH NOP 
* 
*  Get the RDBAP copy's class number from its entry in the scheduling table 
*  and call #RQUE.
* 
      LDA ENTAD 
      ADA BPCLS 
      LDB A,I 
      STB CLAS2 
* 
      JSB #RQUE 
       DEF *+9
       DEF D20N 
       DEF B10K 
       DEF D0       send the data buffer unmodified 
       DEF D0 
       DEF D0       send the request buffer unmodified
       DEF D0 
       DEF CLAS2
       DEF CLASS
* 
      RSS           Error return
      ISZ SWTCH       bump return point.
      JMP SWTCH,I   Return. 
      SKP 
* 
*  RMOVE is a utility subroutine which removes the current request from 
*  RDBAM's class number.
* 
*  The calling sequence for RMOVE is: 
* 
*         CLASS = RDBAM's class number
*         JSB RMOVE 
*        <return point> 
* 
RMOVE NOP 
* 
*  Get class number, remove its save buffer bit, set its save class and 
*  no waits bits. 
* 
      LDA CLASS 
      XOR BIT14 
      STA CLAS2 
* 
*  Go to RTE to release class buffer. 
* 
      JSB EXEC
       DEF *+5
       DEF NA21     Class get, no abort 
       DEF CLAS2
       DEF DUMMY
       DEF D0       No data 
      NOP           Ignore errors.
      JMP RMOVE,I 
      SKP 
* 
*  This short subroutine is bid up when RDBAM is first scheduled and is 
*  unable to find the type 6 file named RDBAP.  It merely prints a warning
*  message to the system console and returns. 
* 
BAPER NOP 
* 
      JSB EXEC
       DEF *+5
       DEF NA2      write, no abort 
       DEF ERLU     error lu passed by LSTEN
       DEF BAMES    warning message 
       DEF D22      message length
      NOP           ignore abort return 
* 
      CLA           Set A to zero so as to skip 
      JMP BAPER,I     call to C.RP on return. 
* 
BAMES ASC 22,/RDBAM - WARNING RDBAP MUST BE IN THE SYSTEM 
* 
D20N  OCT 100024
D22   DEC 22
NA2   OCT 100002
M144  DEC -144
M1    DEC -1
D2    DEC 2 
D3    DEC 3 
* 
MAPHI OCT 17777 
BIT13 OCT 020000
BIT14 OCT 040000
NA19  OCT 100023
NA10  OCT 100012
B10K  OCT 010000
* 
CNTR1 NOP 
CNTR2 NOP 
TABAD NOP 
ENTAD NOP 
EMPTY NOP 
INDEX NOP 
TEMP  NOP 
      END RDBAM 
      END$
                                                                                                                                                                                        