// DATE 040222
// NOHALT
*
*** RUN MAINT.
*
// LOAD $MAINT,F1
// RUN
// COPY FROM-READER,TO-F1,RETAIN-R,LIBRARY-S,NAME-$TORI
       MACRO
       $TORI
.*
.*     5703-XM1 STORE IN NULL DIRECTORY BLOCK
.*
       TEXT
       TITLE 'STORIN - STORE IN NULL DIRCTY BLOCK SUBROUTINE'
***********************************************************************
*  5703-XM1 COPYRIGHT IBM CORP, 1970                                  *
*           REFER TO INSTRUCTIONS ON COPY RIGHT NOTICE, 120-2083      *
*                                                                     *
***********************************************************************
*STATUS                                                               *
*   VERSION 1 MODIFICATION 0                                          *
*                                                                     *
*FUNCTION                                                             *
*   * STORIN WILL INSERT AN ENTRY IN THE NULL DIRECTORY. IF THE ENTRY *
*     IS CONTIGUOUS WITH ANY OTHER ENTRY ALREADY IN THE DIRECTORY, IT *
*     IS COMBINED WITH THAT ENTRY, IF THE ENTRY IS CONTIGUOUS TO TWO  *
*     ENTRIES THE THREE ENTRIES ARE COMBINED INTO ONE AND THE         *
*     DIRECTORY IS COMPRESSED,                                        *
*   * IF THE ENTRY IS NOT CONTIGUOUS TO ANY OTHER ENTRY IT IS ADDED   *
*     TO THE END OF THE DIRECTORY OR INSERTED IN SEQUENCE.            *
*   * IF THE DIRECTORY IS FULL THE INDICATOR IN SMIND1 IS SET AND     *
*     THE RETURN TAKEN,                                               *
*                                                                     *
*ENTRY POINTS                                                         *
*     STORIN - ENTRY TO STORE A NULL ENTRY IN THE DIRECTORY. @BR      *
*              AND @XR ARE SAVED AND RESTORED ON RETURN.  THE         *
*              CALLING SEQUENCE IS AS FOLLOWS:                        *
*                    B STORIN                                         *
*              RETURN IS TO THE FIRST INSTRUCTION FOLLOWING THE       *
*              BRANCH TO STORIN,                                      *
*                                                                     *
*INPUT                                                                *
*   * THE ADDRESS OF THE LEFT BYTE OF THE ENTRY TO BE MADE IN THE     *
*     DIRECTORY MUST BE IN SMNETD,                                    *
*   * THE ADDRESS OF THE NULL DIRECTORY MUST BE IN SMNDBA.            *
*                                                                     *
*OUTPUT                                                               *
*   NONE.                                                             *
*                                                                     *
*EXTERNAL REFERENCES                                                  *
*      SMNETD - LOCATION OF THE ADDRESS OF THE ENTRY                  *
*      SMNDBA - LOCATION OF NULL DIRECTORY BUFFER ADDRESS.            *
*      SMIND1 - LOCATION OF INDICATOR BYTE IN TSMLES.                 *
*      SM1STN - VALUE OF FULL DIRECTORY INDICATOR.                    *
*                                                                     *
*EXITS, NORMAL                                                        *
*   RETURN IS TO THE LOCATION POINTED TO BY THE @ARR. IF THE ENTRY    *
*   WAS MADE SM1STN IS 0, IF THE DIRECTORY IS FULL AND THE ENTRY      *
*   CAN NOT BE MADE SM1STN IN SMIND1 IS SET TO 1.                     *
*                                                                     *
*EXITS, ERROR                                                         *
*   NONE                                                              *
*                                                                     *
*TABLES/NORKAREAS                                                     *
*   NONE                                                              *
*                                                                     *
*ATTRIBUTES                                                           *
*   RELOCATABLE, REUSABLE                                             *
*                                                                     *
*CHARACTER CODE DEPENDENCY                                            *
*   THE OPERATION OF THIS MODULE DEPENDS UPON AS INTERNAL             *
*   REPRESENTATION OF THE EXTERNAL CHARACTER SET WHICH IS EQUIVALENT  *
*   TO THE USED AT ASSEMBLY TIME, THE CODING HAS BEEN ARRANGED SO     *
*   THAT REDEFINITION OF THE CHARACTER CONSTANTS, BY REASSEMBLY, WILL *
*   RESULT IN A CORRECT MODULE FOR THE NEW DEFINITIONS.               *
*                                                                     *
*NOTES                                                                *
*   ERROR PROCEDURES                                                  *
*      NONE                                                           *
*                                                                     *
*   REGISTER USAGE                                                    *
*      * @BR AND @XR ARE SAVED AND RESTORED ON RETURN.                *
*        @ARR IS SAVED IN THE BRANCH TO RETURN.                       *
*      * @BR IS USED AS A BASE REGISTER DURING EXECUTION.             *
*        @XR IS USED A POINTER TO THE NULL DIRECTORY.                 *
*                                                                     *
*   SAVED/RESTORED AREAS                                              *
*      NONE                                                           *
*                                                                     *
*   MODIFICATION CONSIDERATIONS                                       *
*      TO CALCULATE THE END OF THE NULL DIRCTY STORIN MULTIPLIES THE  *
*      NUMBER OF ENTRIES BY SIX,  IF THE LENGTH OF THE NULL ENTRY IS  *
*      CHANGED, THIS CODING MUST BE UPDATED.                          *
*                                                                     *
*   REQUIRED MODULES                                                  *
*        @SYSEQ - SYSTEM SOFTWARE EQUATES                             *
*        @DIREQ - LIBRARY DIRECTORY EQUATES                           *
*        TSMLES - DATA MANAGEMENT COMMUNICATIONS AREA                 *
*                                                                     *
*   OTHER                                                             *
*      NONE                                                           *
***********************************************************************
       EJECT
STORIN EQU   *                         ENTRY TO STORE IN NULL DIRCTY
       USING STOR30,@BR                BASE
       ST    STOR90+@OP1,@BR           SAVE BASE
STORE1 EQU   1                         Q CODE VALUE
       LA    STOR30,@BR                LOAD BASE ADDR
       ST    STOR95+@OP1(,@BR),@XR     SAVE INDEX
       ST    STOR99+@OP1(,@BR),@ARR    SAVE RETURN
*
*            INITALIZE POINTERS AND COUNTERS
*
       MVI   STOR31(,@BR),@NOP         NO PREVIOUS ENTRY SWITCH
       MVC   STOR35+@OP1(@CADDR,@BR),STO70A(,@BR)  NEW ENTRY SWITCH
       L     SMNETD,@XR                GET NEW ENTRY ADDR
       MVC   STORWE(STOENL,@BR),##DNEF(,@XR)  MOVE INTO WORKAREA
       L     SMNDBA,@XR                PICKUP POINTER TO BUFFER AREA
       ST    STOR45(,@BR),@XR          SAVE BUFFER ADDR
       ST    STO048+@OP1(,@BR),@XR     SAVE BUFFER POINTER
       MVC   STOENC(##LAHC,@BR),##DPHC(,@XR)  COUNT TO NEW ENTRY
       MVC   STORWC(##LAHC,@BR),##DPHC(,@XR)  PICKUP ENTRY COUNT
*
*            TEST ENTRY COUNT FOR MAX ENTRIES OR ZERO ENTRIES
*
       CLI   STORWC(,@BR),##MNHM       TEST MAX ENTRY COUNT
       JE    STOR10                    GO SET SWITCH NO NEW ENTRIES
       MVI   STOR70+@Q(,@BR),@NOP      SET SWITCH TO ALLOW ENTRY
       CLI   STORWC(,@BR),@ZERO        TEST IF DIRCTY EMPTY
       JNE   STOR14                    GO COMPARE ENTRIES
*
       MVI   ##DNHC(,@XR),STORE1       INITIALIZE COUNTER
*
*            MOVE THE ENTRY INTO THE DIRCTY
*
       MVC   ##LNH+##DNER(##LNE,@XR),STORWE+##LNEZ(,@BR)
       B     STOR90(,@BR)              GO RETURN
*
STOR10 MVI   STOR70+@Q(,@BR),@UCB      SWITCH NO NEW ENTRIES
STOR14 LA    ##DNE1(,@XR),@XR          BUMP TO FIRST ENTRY
STOR15 CLC   STORWE-##LNEF(@DADDR,@BR),##DNEA(,@XR)  COMPARE NEW/DIRCTY
       JL    STOR20                    NEW LOWER
       ST    STORPA(,@BR),@XR          SAVE PREVIOUS ENTRY ADDR
       SLC   STORWC(1,@BR),STORC1(,@BR)  DECK ENTRY COUNT
       JE    STOR47                    GO SETUP TO CALC CURRENT HIGH
       MVI   STOR31(,@BR),@UCB         SET PREVIOUS ENTRY SWITCH
       LA    ##LNE(,@XR),@XR           BUMP POINTER TO NEXT ENTRY
       B     STOR15                    BACK FOR NEXT ENTRY
*
*            FOUND POSSIBLE POSITION FOR NEW ENTRY
*
STOR20 MVC   STORWK(STOENL,@BR),STORWE(,@BR)
       B     STOR60(,@BR)              GO CALC HIGH END
*
*            TEST IF ADDR OF HIGH END IS CONTIGUOUS TO NEXT ENTRY
*
       MVI   STO39A+@Q(,@BR),@NOP      DONT COMBINE
       CLC   STORCS(@CADDR,@BR),##DNEA(,@XR)  COMPARE ADDR
       JNE   STOR30                    JUMP NOT CONTIGUOUS
       ALC   ##DNEF(##LNEF,@XR),STORWE(,@BR)  ADD NEW COUNT TO ENTRY
       MVC   ##DNEA(@DADDR,@XR),STORWA(,@BR)  MOVE IN NEW ENTRY
*
       MVC   STOR35+@OP1(@CADDR,@BR),STORET(,@BR)  GET RETURN CADDR
       MVI   STO39A+@Q(,@BR),@UCB      ALLOW ENTRIES BE COMBINED
*
*            TEST IF PREVIOUS ENTRY THAT MAY BE CONTIGUOUS.  TEST IF
*            SWITCH ON OR OFF, @UCB IS ON. @NOP IS NO PREVIOUS ENTRY.
*
STOR30 JC    STOR38,*-*                PREVIOUS ENTRY SWITCH
STOR31 EQU   STOR30+@Q
*
*            IF NEW ENTRY TO BE ADDED GO TO STOR70.  IF NO NEW ENTRY
*            GO TO RETURN ROUTINE.
*
STOR35 B     *-*                       RETURN OR GO MAKE ENTRY
*
*            SET UP TO CALCULATE HIGH END ADDR OF PREVIOUS ENTRY
*            PICK UP THE DISPLACEMENT TO THE PREVIOUS ENTRY
*
STOR38 ALC   STORPA(@CADDR,@BR),STOCLN(,@BR)  BUMP TO RIGHT END
       MVC   STOR39+@DOP2(@CADDR,@BR),STORPA(,@BR)
STOR39 MVC   STORWK(STOENL,@BR),*-*    MOVE PREVIOUS ENTRY TO WORKAREA
*
       B     STOR60(,@BR)              CALC HIGH END
*
       CLC   STORCW(@DADDR,@BR),STORCS(,@BR)
       BNE   STOR35(,@BR)              GO RETURN OR MAKE NEW ENTRY
STO39A JC    STOR40,*-*                SWITCH FOR COMBINING ENTRIES
*
*            NEW ENTRY IS CONTIGUOUS TO PREVIOUS ENTRY BUR NOT NEXT
*
       MVC   STO39B+@OP1(@CADDR,@BR),STORPA(,@BR)
STO39B ALC   *-*,STORWE(##LNEF,@BR)    NEW COUNT TO PREVIOUS ENTRY
       J     STOR90                    GO RETURN
*
*            NEW ENTRY HAS FILED A SPACE BETWEEN TO FORMER ENTRIES.
*            COMBINE THE THREE ENTRIES INTO THE FIRST ENTRY.
*
STOR40 ALC   *-*,##DNEF(##LNEF,@XR)    ADD COUNT FIELDS
STORPA EQU   STOR40+@OP1
*
*            PICK UP POINTER TO START OF BUFFER TO DECR COUNT
*
STOR46 SLC   *-*,STORC1(##LAHC,@BR)    DECR HEADER ENTRY COUNT
STOR45 EQU   STOR46+@OP1               ADDR OF DIRCTY ADDR
       LA    ##DNER(,@XR),@XR          BUMP TO RIGHT END
*
       SLC   STORWC(1,@BR),STORC1(,@BR)  DECR WORK ENTRY COUNT
       JE    STOR90                    IF LAST ENTRY RETURN
*
*            SET UP POINTERS TO SQUEEZE UP THE DIRCTY. THE CURRENT
*            ENTRY IS DELETED BY OVERLAYING IT WITH THE REMAINDER OF
*            THE DIRCTY.
*
       ST    STOR52(,@BR),@XR          SAVE THE TO ADDR
       LA    ##LNE(,@XR),@XR           BUMP TO NEXT ENTRY
       ST    STOR53(,@BR),@XR          SET THE FROM CADDR
       MVC   STORAM(@CADDR,@BR),STOREL(,@BR)  POSITIVE MODIFIER
       B     STOR50(,@BR)              GO MOVE ENTRY
STO047 B     STOR90                    GO RETURN
STORET EQU   STO047+@OP1               POINTER TO RETURN ACTION
*
*            ALL ENTRIES TESTED, CURRENT ENTRY LAST ONE.  CALCULATE
*            HIGH END ADDR TO CHECK IF NEW ENTRY IS CONTIGUOUS.
*
STOR47 MVC   STORWK(STOENL,@BR),##DNEF(,@XR)
*
       B     STOR60(,@BR)              GO CALC HIGH END
*
*            TEST IF HIGH ADDR EQUAL TO START OF NEW ENTRY, IF NO GO
*            MAKE NEW ENTRY, IF YES ADD NEW COUNT TO CURRENT ENTRY.
*
       CLC   STORCW(@CADDR,@BR),STORCS(,@BR)  TEST HIGH AND NEW ENTRY
       JE    STOR48                    JUMP IF CONTIGUOUS
       CLI   STOR70+@Q(,@BR),@UCB      TEST IF NEW ENTRY IS ALLOWED
       JE    STOR80                    ERROR EXIT
       LA    ##LNE(,@XR),@XR           BUMP TO NEXT ENTRY
       MVC   ##DNER(##LNE,@XR),STORWE+##LNEZ(,@BR)  MOVE IN ENTRY
STO048 ALC   *-*(##LAHC),STORC1(,@BR)  BUMP ENTRY COUNT
       J     STOR90                    GO RETURN
*
STOR48 ALC   ##DNEF(##LNEF,@XR),STOREC(,@BR)  NEW COUNT TO CURRENT
       J     STOR90                    GO RETURN
*
*            ERROR RETURN ACTION IF NO ENTRIES CAN BE MADE
*
STOR80 SBN   SMIND1,SM1STN             TURN ON INDICATOR
*
*            ALL ACTION COMPLETE GO BACK TO CALLER
*
STOR90 LA    *-*,@BR                   RESTORE CALLERS REGS
STOR95 LA    *-*,@XR
STOR99 B     *-*                       RETURN TO THE CALLER
       EJECT
***********************************************************************
*            CONSTANTS AND WORK AREA                                  *
***********************************************************************
STORWE DS    IL(@DADDR+##LNEF)         WORK AREA FOR NEW ENTRY
STORCW EQU   STORWE-##LNEF             NEW ENTRY ADDR
STOREC EQU   STORWE                    POINTER TO ENTRY COUNT
STORWA EQU   STORWE-##LNEF             ENTRY ADDR
STOCLN DC    AL2(##DNEF)               DISPLACEMENT TO RIGHT END
STORDR DC    AL2(@ZERO-##LNEZ)
STOREL DC    AL2(##LNE)                INCR POINTERS
STOC48 DC    IL2'48'                   INCR POINTERS
STORNM DC    AL2(@ZERO-##LNE)          NEGATIVE MODIFIER
STORWC DS    AL(##LAHC)
STORC1 DC    IL2'1'                    INCR VALUE FOR COUNTERS
STORE2 EQU   2                         FIELD LENGTH FOR ADD AND SUBTR
STORAM DS    IL(@CADDR)                ADDR MODIFIER FOR MOVE ROUTINE
STOENL EQU   @DADDR+##LNEF             LENGTH OF ADDR AND SECTOR COUNT
STOENC DS    IL2                       ENTRY COUNT
STO70A DC    AL2(STOR70)               CADDR OF INSERT NEW ENTRY
STORHL DC    AL2(##LNH)                LENGTH OF HEADER
STOENA DC    AL2(STORWE)               ADDR OF ENTRY
       EJECT
*
*            THE FOLLOWING SUBROUTINE WILL MOVE THE END PORTION OF
*            THE DIRCTY FORWARD OR BACKWARD DEPEND1NG ON THE VALUE
*            OF THE MODIFIER PLUGGED IN BY THE CALLING ROUTINE.
*            THE TO AND FROM ADDR FOR THE MOVE ARE ALSO PLUGGED IN
*            BY THE CALLING ROUTINE,
*
STOR50 ST    STO067+@OP1(,@BR),@ARR    SAVE RETURN
*
STOR51 MVC   *-*(##LNE),*-*            MOVE ENTRY AS SPECIFIED
STOR52 EQU   STOR51+@OP1               LOCATION OF TO ADDR
STOR53 EQU   STOR51+@OP2               LOCATION OF FROM ADDR
STOR55 SLC   STORWC(1,@BR),STORC1(,@BR)  DECR WORK COUNT
       JE    STO067                    ZERO COUNT RETURN
       ALC   STOR52(@CADDR,@BR),STORAM(,@BR)  MODIFY THE TO ADDR
       ALC   STOR53(@CADDR,@BR),STORAM(,@BR)  MODIFY FROM ADDR
       B     STOR51(,@BR)            GO MOVE NEXT ENTRY
       SPACE 3
*
*            THE FOLLOWING ROUTINE WILL CALCULATE THE HIGH END ADDR
*            OF THE SPECIFIED ENTRY.
*
STOR60 ST    STO067+@OP1(,@BR),@ARR    SAVE RETURN
STORWK EQU   STOR53                    WORK AREA TO CALC HIGH ADOR
STORC0 EQU   STORWK-##DNEF             POINTER TO LEFT BYTE
STORCS EQU   STORWK-##LNEF             ENTRY DADDR
*
       MVC   STO064+@Q(,@BR),STORC0(1,@BR)  GET CYL BYTE
       MVI   STORC0(,@BR),@ZERO        CLEAR HIGH ORDER CYL BYTE
       ALC   STORCS(##LNEF,@BR),STORWK(,@BR)  ADD IN LENGTH
*
STOR65 SLC   STORCS(STORE2,@BR),STOC48(,@BR)  DECR IT CYL VALUE
       JL    STOR66                    GO RESTORE
*
       ALC   STO064+@Q(1,@BR),STORC1(,@BR)  BUMP CYL
       B     STOR65(,@BR)             BACK TO DECK AGAIN
STOR66 ALC   STORCS(STORE2,@BR),STOC48(,@BR)  RESTORE REMAINDER
STO064 MVI   STORC0(,@BR),*-*          MORE CYL COUNT
STO067 B     *-*                       RETURN
       SPACE 3
*
*            THE FOLLOWING ROUTINE WILL INSERT A NEW ENTRY INTO THE
*            DIRCTY IF THE SWITCH HAS BEEN SET TO ALLEW ENTRIES, IF
*            A NEW ENTRY MUST BE MADE AND THE DIRCTY IS FULL THE ERROR
*            EXIT IS TAKEN AND AN INDICATOR IS SET TO NOTE THE LIERART
*            AREA SHOULD BE PACKED.
*            NOTE - THIS ROUTINE DEPENDS ON THE NULL ENTRY BEING SIX
*            BYTES.
*
STOR70 BC    STOR80,*-*                BRANCH IF FULL SWITCH SET
*
STOSAV EQU   STO067+@OP1               TEMP WORK AREA
       MVI   STOENC-1(,@BR),@ZERO      CLEAR HIGH ORDER BYTE
       MVI   STOSAV-1(,@BR),@ZERO      CLEAR HIGH ORDER BYTE
       ALC   STOENC(##LNEF,@BR),STOENC(,@BR)  DOUBLE COUNT
       MVC   STOSAV(1,@BR),STOENC(,@BR)       SAVE COUNT*2
       ALC   STOENC(##LNEF,@BR),STOSAV(,@BR)  *4
       ALC   STOENC(##LNEF,@BR),STOSAV(,@BR)  *6
       ALC   STOENC(STORE2,@BR),STORHL(,@BR)  ADD HDR LENGTH
       ALC   STOENC(@CADDR,@BR),SMNDBA        ADD START BUFFER
       SLC   STOENC(@CADDR,@BR),STORC1(,@BR)  BACK TO RIGHT END
       MVC   STOR53(@CADDR,@BR),STOENC(,@BR)  FROM ADDR
       ALC   STOENC(@CADDR,@BR),STOREL(,@BR)  BUMP TO RIGHT NEXT ENT
       MVC   STOR52(@CADDR,@BR),STOENC(,@BR)  TO ADOR
       MVC   STORAM(@CADDR,@BR),STORNM(,@BR)  NEGATIVE MODIFIER
       B     STOR50                    BRANCH TO MOVER ROUTINE
*
*            MOVE THE NEW ENTRY INTO THE VACATED CURRENT ENTRY LOCATION
*
       MVC   ##DNER(##LNE,@XR),STORWE+##LNEZ(,@BR)  MOVE THE ENTRY IN
       B     STO048(,@BR)              GO RETURN
       SPACE
***********************************************************************
***                       END OF STORIN                             ***
       MEND
// CEND
// END
*
// READER CONSOLE
