ASMB,L,C,R HED DBMST IMAGE/1000 UTILITY SUBROUTINE NAM DBMST,7 92069-16155 REV.1912 790130 * * ******************************************************************* * (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-18155 * RELOC: 92069-16155 * * PRGMR: CEJ * * ******************************************************************* * * * * MaSTer put is a utility subroutine used by DBPUT to determine the * proper record number for a new master data set entry and to build the * media record in the record buffer for that entry * * The calling sequence for DBMST is: * * JSB DBMST * DEF *+5 * DEF BASE data base # from ibase parameter * DEF MSNUM master data set's # * DEF READ the READ flag from DBHRD * DEF RECRD the record # from DBHRD * * * DBMST returns a condition code in the A register, zero if successful. * * DBMST must be called immediately after DBHRD or before any of the * values passed back by DBHRD have been altered. It uses the READ flag * and RECRD number returned by DBHRD to determine the new master record * number and to build the new entry's media record. When we enter the * routine we assume that the READ flag is not zero since this would * mean that a master entry already exists with the new entry's key item * value and the new entry could not be added. If the READ flag is > 0, * the new record should go into the record whose number was passed by * DBHRD in RECRD, however, that record contains a synonym for another * chain. Therefore, we must move it. If the READ flag is < 0, we have * to check the record in the record buffer itself to decide what to do. * If the record is empty, we've hit the simplest case. The new record * is put into the record whose number was passed to us with no synonyms. * If the record is non-empty, it contains the current synonym chain foot * for the new record's synonym chain. We need to find the next free re- * cord in the master (searching serially from the record number: RECRD) * and make the new record the end of the synonym chain. * * Our first action is to resolve the parameter and return point addresses. * ENT DBMST EXT .DIS,.DCO,.ENTR,AIRUN,DBFCB,DBFDS,DBFWZ,DBRBL EXT DBRBP,DBRED,DBWRT,EREAD A EQU 0 B EQU 1 * BASE NOP MSNUM NOP READ NOP RECRD NOP * DBMST NOP JSB .ENTR DEF BASE * CLA Set the primary FLAG STA FLAG to true. * * We will deal with a synonym belonging to a different chain than the * new record first. This means, move the synonym to the next (serially) * free record in the master. Then, put the new record in the synonym's * old record as a primary with "no" synonyms. * LDA READ,I SSA Is READ flag > 0? JMP MST3 No - we deal with that later. * DLD RECRD,I Yes - save this record # DST SAVE1 * JSB DBFFR Ask DBFFR to give us the next * free record in the data set. * LDA RECRD,I Did DBFFR succeed? SSA (i.e. record # non-negative?) JMP MSTE No - inform caller. * JSB DBWRT Yes - write the synonym to DEF *+4 the new record. DEF BASE,I DBWRT needs: data base # DEF MSNUM,I data set # DEF RECRD,I record number * SZA Did DBWRT encounter an error? JMP MSTR Yes - pass it to the user. * LDA DBRBP No - save off synonym's forward ADA D3 and backward synonym DLD A,I chain pointers. DST FRWRD LDA DBRBP INA DLD A,I DST BKWRD * * Update any synonyms which point to the record we just moved. * SZB,RSS Was it's backward pointer = 0? SZA RSS JMP E154 Yes - we've got a corrupt chain. * JSB DBRED No - read the backward pointer DEF *+4 DEF BASE,I DEF MSNUM,I DEF BKWRD * SZA Did DBRED encounter an error? JMP MSTR Yes - pass it to user. * LDA DBRBP No - make its forward pointer ADA D3 the synonym's new record # STA TEMP DLD RECRD,I DST TEMP,I * JSB DBWRT and write it back to disc. DEF *+4 DEF BASE,I DEF MSNUM,I DEF BKWRD * SZA Any error? JMP MSTR Yes - pass it to the user. * CPA FRWRD+1 No - was synonym's forward pointer = 0? RSS JMP MST1 CPA FRWRD JMP MST2 Yes - we are through w/synonym. * MST1 JSB DBRED No - read the forward pointer. DEF *+4 DEF BASE,I DEF MSNUM,I DEF FRWRD * SZA Any error? JMP MSTR Yes - pass it to user. * LDA DBRBP No - make it's backward pointer INA the synonym's new record #. STA TEMP DLD RECRD,I DST TEMP,I * JSB DBWRT Then, write it back out to disc. DEF *+4 DEF BASE,I DEF MSNUM,I DEF FRWRD * SZA Any error? JMP MSTR Yes - pass it to user. * MST2 DLD SAVE1 Done with synonym move. DST RECRD,I Put new entry's record # JMP MST4 back into RECRD for joint processing. SKP * * Now, we'll deal with the case of the new record belonging to an al- * ready existant synonym chain. (Remember that this case is signified * by the READ flag < 0 and the entry in the record buffer being non- * empty.) This case is handled by finding the next free record in the * data set from the current record number. The new record is flagged * as a synonym by setting the primary FLAG to FALSE (-1) and storing the * current record number (the old end of synonym chain) in the SYNYM * storage area. * * The READ flag is already known to be less than zero, so we start by * checking the entry type. The type flag is the first word of the media * record of the entry. It is non-zero if the entry is empty. * MST3 LDA DBRBP,I Is the current entry empty? SZA,RSS JMP MST4 Yes - simple case. * DLD RECRD,I No - save the record as the old DST SYNYM synonym chain foot. CCA Set the primary flag to FALSE. STA FLAG * JSB DBFFR Get the next free record * in the master set. * LDA RECRD,I Did we get it? SSA Yes - continue to joint processing. JMP MSTE No - let the caller know. SKP * * There is no special processing for the simple case of DBHRD not find- * ing a synonym for the new record's key value and not finding a synonym * in its proper primary location. So we just join all cases here. * * We have the new record's proper record number in RECRD. If it is a * synonym (primary FLAG = FALSE) we have the old synonym chain foot's * record number in SYNYM. Now all we have to do is build the new record * in the record buffer by setting its proper entry type in the first * word of the media record to: * 1 - if a primary entry (FLAG = TRUE) * -1 - if a synonym entry (FLAG = FALSE) * and if a synonym, setting the backward synonym pointer (2nd & 3rd words * of media record) to SYNYM. The remainder of the media record is all * zeroes. * MST4 JSB DBFWZ Fill the record buffer with zeroes. DEF *+3 DEF DBRBL DBFWZ needs: length of area to zero DEF DBRBP address of area to zero * CLB,INB If a primary entry, set LDA FLAG entry type to 1 SSA else set entry typ CMB,INB to -1. STB DBRBP,I * SSA,RSS If a synonym, put SYNYM JMP MSTE in new record's backward LDB DBRBP synonym chain pointer. INB STB TEMP DLD SYNYM DST TEMP,I * * Return to caller. * MSTE CLA MSTR JMP DBMST,I * * Error return point. * E154 LDA D154 Corrupt chain pointers. JMP MSTR * * Constants and variables. * D3 DEC 3 D154 DEC 154 SYNYM BSS 2 FRWRD BSS 2 BKWRD BSS 2 SAVE1 BSS 2 TEMP NOP FLAG NOP SKP * * Find Free Record is a utility subroutine for DBMST. It performs the * service of finding the next free record in a master data set (MSNUM) * by searching serially through the data set from the current record * number (in RECRD) until a free record is found or a complete wrap around * on the set has been performed. If it finds a free record, it returns * the number of that record in RECRD. If it does not find a free record, * it sets RECRD to -1. * DBFFR NOP * * Save current record number in RECRD as starting point. * DLD RECRD,I DST START * * Ask DBFCB to give us the data set's DCB. * JSB DBFCB DEF *+4 DEF BASE,I DBFCB needs: data base number DEF MSNUM,I data set number DEF MSDCB returns: DCB address * SZA Did DBFCB encounter an error? JMP MSTR Yes - return in to user. * * Ask DBFDS to get MSNUM'S DSCB pointer for us. * JSB DBFDS DEF *+5 DEF MSNUM,I DEF NUMBR DEF ENTYP DEF MSPTR * LDA NUMBR If set # came back SZA,RSS as zero JMP FFRE bad Run Table. * * Get the address of the capacity in the DSCB (9th word) and save it * in MSPTR. * LDA MSPTR ADA AIRUN ADA CAPAC STA MSPTR * * Now read serially through the data set searching for an empty record. * we need only the first word of each entry since it contains the entry * type flag (will be zero for an empty record). * FFR1 JSB .DIS Increment the record #. DEF RECRD,I NOP * * Check to see if the new record number is greater than the capacity. * If so, set the record number to 1 before we read it. * DLD MSPTR,I JSB .DCO DEF RECRD,I RSS Record # = capacity. RSS Record # > capacity. JMP FFR2 Record # < capacity. * CLA CLB,INB DST RECRD,I * FFR2 DLD START JSB .DCO DEF RECRD,I If same as starting record JMP FFRE we've completely wrapped NOP around data set. * JSB EREAD Read the first word of the record. DEF *+7 DEF MSDCB,I DEF ERROR DEF ENTYP DEF D1 DEF DUMMY (merely a place holder) DEF RECRD,I * SSA Did we get an error? JMP MSTR Yes - pass the error to the user. * * Here on a successful read, check the entry type in ENTYP. If it is * zero - we've got the record we want, pass it back to the caller. * LDA ENTYP SZA JMP FFR1 * FFR4 JMP DBFFR,I * * Error return point - no empty record found. * FFRE CCB CCA DST RECRD,I JMP FFR4 * * Constants and variables * D1 DEC 1 CAPAC DEC 8 START BSS 2 ENTYP NOP ERROR NOP NUMBR NOP DUMMY EQU NUMBR MSDCB NOP MSPTR NOP END