* NEXTFST ROUTINE
* GIVEN A PLIST OF THE FORM
*  A(FILENAME)
*  A(FST)
*  A(ADT)
* WHERE FILENAME IS A CMS FILENAME (FN,FT,FM), POSSIBLY CONTAINING
* WILDCARD CHARACTERS, AND FST AND ADT POINT TO VALID ADTS AND FSTS
* OR ARE NULL (DESIGNATED BY X'FF000000'), RETURN THE NEXT FST
* MATCHING THE GIVEN FILENAME IN FST AND THE ADDRESS OF THE
* CORRESPONDING ADT IN ADT.
*
* CARL KASS AND JEFF DAMENS, CUCCA USER SERVICES, 12/80
* COPYRIGHT (C) 1980 COLUMBIA UNIVERSITY
* PERMISSION IS GRANTED TO ANY INDIVIDUAL OR INSTITUTION TO COPY 
* OR USE THIS PROGRAM, EXCEPT FOR EXPLICITLY COMMERCIAL PURPOSES.  
*
NEXTFST  CSECT
         USING     NEXTFST,15          ADDRESSABILITY
         STM       14,12,12(13)        SAVE REGS
         LR        14,13               SAVE REG 14
         L         13,=V(NEXTFSTA)     DATA AREA
         USING     NEXTFSTA,13         POINT TO DATA AREA
         ST        14,4(13)            BACKCHAIN
         ST        13,8(14)            FORECHAIN
         DROP      15
         BALR      12,0                ESTABLISH FINAL...
         USING     *,12                ...ADDRESSABILITY
*
         USING     NUCON,0             NUCON IS AT BOTTOM
         LR        11,1                POINT AT PAB
         USING     PAB,11              TELL ASSEMBLER
         L         9,PABFN             GET ADDRESS OF COPYED FN
         USING     PASSFI,9
         MVC       COPYFI,PASSFI       COPY IT TO MY STORAGE
         LA        1,COPYFN+8          ADDR OF COPYED FN
         TRT       COPYFN(8),NSPC      LOOK FOR SPACE
         LA        2,COPYFN
         SR        1,2                 COMPUTE LENGTH
         STH       1,PFNL
         LA        1,COPYFT+8          INITIALIZE TO END
         TRT       COPYFT(8),NSPC      LOOK FOR SPACE
         LA        2,COPYFT
         SR        1,2                 FIGURE LENGTH
         STH       1,PFTL
* NOW CHECK THE FILEMODE, IF LETTER IS BLANK SET TO "A",
* IF NUMBER IS BLANK SET TO "%"
         CLI       COPYFM,C' '         IS LETTER BLANK?
         BNE       FMLNBLK             IF NOT THEN BRANCH
         MVI       COPYFM,C'A'         SET TO A IF WAS BLANK
FMLNBLK  EQU       *
         CLI       COPYFM+1,C' '       IS NUMBER BLANK?
         BNE       FMNNBLK             IF NOT THEN BRANCH
         MVI       COPYFM+1,C'%'       SET TO % IF WAS BLANK
FMNNBLK  EQU       *
         L         2,PABADT            ADDR OF THE ADT THEY COPYED
         L         3,PABFST            ADDR OF COPYED FST
         CLC       0(4,2),=X'FF000000' WAS IT NULL?
         BE        ADTNULL
         CLC       0(4,3),=X'FF000000'
         BNE       NNULL2              BOTH ARE NON-NULL
         LA        15,8                ONE IS NULL, ONE ISN'T
         B         DONE                GO HOME
ADTNULL  EQU       *
         CLC       0(4,3),=X'FF00000000' IS THE FST NULL?
         BE        BOTHNULL            BOTH ARE NULL
         LA        15,8                ONE NULL, ONE ISN'T
         B         DONE                GO HOME
* IF WE GET HERE, NO ADT OR FST WAS COPYED, SO WE JUST USE THE
* FIRST ONE THAT MATCHES THE FILEMODE
BOTHNULL EQU       *
         L         10,IADT             GET FIRST ADT
         USING     ADTSECT,10          TELL THE ASSEMBLER
FINDHIS  EQU       *         LOOK FOR THE FIRST ADT THAT MATCHES
*                            WHAT HE COPYED
         TM        ADTFLG1,ADTFRO+ADTFRW  IS IT A CMS DISK?
         BZ        GETNDSK             NO, KEEP GOING
         LA        1,1                 LENGTH IS ONE
         STH       1,STRINGL1          FIRST STRING
         STH       1,STRINGL2          SECOND STRING
         MVC       STRINGT1(1),COPYFM  HIS FM
         MVC       STRINGT2(1),ADTM    THE ONE ON DISK
         L         15,=V(WILD)         THE COMPARE ROUTINE
         LA        1,WILDPAB           THE PARAMETERS FOR IT
         BALR      14,15               CALL IT
         LTR       15,15               TEST RETURN CODE
         BZ        HAVEDISK            MATCHES, GOT IT
GETNDSK  EQU       *                   NOPE, TRY NEXT ONE
         L         10,ADTPTR           GRAB NEXT ADT
         LTR       10,10               CHECK IT
         BNZ       FINDHIS             KEEP GOING IF NOT END
         LA        15,4                CAN'T FIND IT
         B         DONE                GO HOME
HAVEDISK EQU       *                   R10 HAS THE ADT
         L         1,ADTFDA            GRAB HYPERBLOCK PTR
         ST        1,HYPE              SAVE FOR LATER
         USING     DCHSECT,1
         LA        8,DCHDATA           POINT TO FIRST FST
         L         3,DCHDWSIZ          GET SIZE OF HYPERBLOCK
         SLL       3,3                 CONVERT TO BYTES
         LA        2,DCHSECT(3)        ADD TO GET END OF HYPERBLK
         ST        2,HYPEND            SAVE IT
         DROP      1
         B         MTCHFILE            GO LOOK FOR HIS FILE
NNULL2   EQU       *         BRANCH HERE WHEN WE HAVE COPYED ADT & FST
         L         10,PABADT           GRAB ADDR OF COPYED ADT
         L         10,0(10)            GET THE COPYED ADT
         TM        ADTFLG1,ADTFRO+ADTFRW         IS IT ACCESSED?
         BNZ       HISADTOK            YES, KEEP GOING
         LA        15,20               USE RIGHT COND CODE
         B         DONE                AND GO HOME.
HISADTOK EQU       *                   HIS ADT IS ACCESSED.
*                                      LOOK FOR HIS FST & HYPERBLOCK
         L         1,ADTFDA            GET FIRST HYPERBLOCK ADDR
         USING     DCHSECT,1
         L         3,PABFST            POINT TO HIS FST
FSTLOOK  EQU       *
         LA        2,DCHDATA           THIS IS WHERE FST'S START
         C         2,0(3)              COMPARE WITH HIS FST
         BH        LOOKNXT             GET NEXT HYPERBHOCK
         L         4,DCHDWSIZ          GET SIZE IN DWORDS
         SLL       4,3                 MULTIPLY BY 8 TO GET BYTE #
         LA        2,DCHSECT(4)        ADD TO GET BOTTOM OF HYPERBLK
         C         2,0(3)              COMPARE WITH BOTTOM
         BH        GOTHBLK             LESS, WE FOUND IT
LOOKNXT  EQU       *
         LR        4,1                 SAVE THIS
         LR        1,4
         L         1,DCHFWPTR          GRAB NEXT HYPERBLK
         LTR       1,1                 TEST IT TO SEE IF AT END
         BNZ       FSTLOOK             IF NOT END, KEEP TRYING
         LA        15,16               BAD FST, NAUGHTY, NAUGHTY
         B         DONE                GO HOME.
GOTHBLK  EQU       *                   WE HAVE THE HYPERBLOCK
         ST        1,HYPE              SAVE THE HYPERBLOCK
         ST        2,HYPEND            STORE END OF HYPERBLOCK
         DROP      1                   LOOK OUT FOR THAT CLIFF!!!
         L         8,0(3)              THIS BECOMES CURRENT FST
         LR        3,1
         B         NEXTFILE            SKIP HIS FILE
* ALL INITIALIZED, NOW WE'RE READY TO STEP THROUGH FILES, UNTIL
* WE FIND A MATCH OR RUN OUT.
MTCHFILE EQU       *                   COME HERE TO MATCH HIS FILE
* R8 CONTAINS CURRENT FST, R10 CONTAINS CURRENT ADT, HYPE
* CONTAINS CURRENT HYPERBLOCK, HYPEND HAS END OF HYPERBLOCK
* (TO SEE IF WE'RE DONE)
*
         USING     FSTSECT,8           TELL ASSEMBLER
         CLC       FSTN(8),=8X'00'     IS IT A 0?
         BE        NEXTHYP             END OF THIS, TRY NEXT HYPERBLK
         CLC       FSTN(8),=A(1,0)     THIS IS A KLUDGE
         BE        NEXTFILE            TO CHECK
         CLC       FSTN(8),=A(2,0)     IF IT IS THE DIRECTOR OR
         BE        NEXTFILE            ALLOCMAP AND SKIP IT.
* WHEN WE FIGURE OUT HOW TO DETERMINE IF IT'S A REAL FILE OR
* A CMS INTERNAL FILE, WE WON'T HAVE TO DO IT THIS WAY.
         LA        1,FSTN+8            ASSUME END
         TRT       FSTN(8),NSPC        LOOK FOR FIRST NON-SPACE
         LA        2,FSTN
         SR        1,2                 COMPUTE LENGTH
         STH       1,STRINGL2          SAVE LENGTH
         MVC       STRINGT2(8),FSTN    COPY NAME IN
         MVC       STRINGL1(2),PFNL    LENGTH IS ALSO 8
         MVC       STRINGT1(8),COPYFN  COPY COPYED NAME
         LA        1,WILDPAB           ADDRESS OF PAB
         L         15,=V(WILD)         POINT TO WILD ROUTINE
         BALR      14,15               CALL IT
         LTR       15,15               CHECK CONDITION CODE
         BNE       NEXTFILE            NOT SAME, CONTINUE
         LA        1,FSTT+8
         TRT       FSTT(8),NSPC        LOOK FOR NON SPACE
         LA        2,FSTT
         SR        1,2                 COMPUTE LENGTH
         STH       1,STRINGL2          SAVE IT
         MVC       STRINGL1(2),PFTL    GET LENGTH OF COPYED FT
         MVC       STRINGT1(8),COPYFT  COPY COPYED TYPE
         MVC       STRINGT2(8),FSTT    THE TYPE FROM THE FST
         LA        1,WILDPAB           ADDRESS OF PAB
         L         15,=V(WILD)
         BALR      14,15               CALL FOR TYPE
         LTR       15,15               CHECK CONDITION CODE
         BNE       NEXTFILE            NOPE, TRY NEXT FILE
         MVC       STRINGL1(2),=H'2'   LENGTH OF MODE IS 2
         MVC       STRINGL2(2),=H'2'   DITTO
         MVC       STRINGT1(2),COPYFM  HIS COPYED FILEMODE
         MVC       STRINGT2(1),ADTM    GET REAL MODE LETTER FROM ADT
         MVC       STRINGT2+1(1),FSTM+1 USE MODE NUMBER FROM FST
         LA        1,WILDPAB           ADDRESS OF PAB
         L         15,=V(WILD)
         BALR      14,15               CALL WILD (AGAIN)
         LTR       15,15               LOOK AT CONDITION CODE
         BNZ       NEXTFILE            NOPE, CONTINUE
         L         1,PABADT
         ST        10,0(1)             SAVE ADT FOR HIM
         L         1,PABFST
         ST        8,0(1)              DITTO FOR FST
         SR        15,15               INDICATE SUCCESS
         B         DONE                GO HOME
* COME HERE TO STEP TO NEXT FILE
NEXTFILE EQU       *                   STEP TO NEXT FILE
*  CAN ALSO GO TO NEXTHYP IF APPROPRIATE.
*
* THERE ARE TWO DIFFERENT KINDS OF FSTS (WE THINK FOR 3370'S
* OR 3350'S)... ONE IS CALLED AN EXTENDED DISK FORMAT, AND
* HAS A LONGER FST: ITS LENGTH IS FSTL2.  IF IT ISN'T AN EDF
* DISK, THE LENGTH IS JUST FSTL.  THE NEXT FEW INSTRUCTIONS
* DECIDE WHICH LENGTH TO USE AND ADD THE APPROPRIATE ONE.
*
         TM        ADTFLG4,ADTEDF      IS THIS AN EXTENDED ONE?
         BZ        NOTEDF              NOT EXTENDED DISK FORMAT
         LA        8,FSTL2(8)          POINT TO NEXT FILE
         B         NEXTF2              'CAUSE WE CAN'T SKIP AN INSTR
NOTEDF   EQU       *                   USING THE SHORT FORM OF FST
         LA        8,FSTL(8)           POINT TO NEXT FILE
NEXTF2   EQU       *
         C         8,HYPEND            SEE IF AT END
         BL        MTCHFILE            NOT AT END, KEEP TRYING
*
NEXTHYP  EQU       *                   GO TO THE NEXT HYPERBLOCK
*  OR TO THE NEXT DISK IF NO MORE.
         L         1,HYPE              POINT TO OUR HYPERBLOCK
         USING     DCHSECT,1           TELL ASSEMBLER
         L         1,DCHFWPTR          GRAB NEXT ONE
         LTR       1,1                 SEE IF AT END OF CHAIN
         BZ        NEXTDISK            NEED TO USE NEXT DISK
         ST        1,HYPE              SAVE HYPERBLOCK ADDR
         LA        8,DCHDATA           R8 GETS FIRST FST OF BLOCK
         L         2,DCHDWSIZ          GET SIZE OF BLOCK
         SLL       2,3                 CONVERT TO BYTES
         LA        2,DCHSECT(2)        COMPUTE END OF HYPERBLK
         ST        2,HYPEND            SAVE END
         B         MTCHFILE            KEEP TRYING TO MATCH
         DROP      1                   DON'T BREAK IT
*
NEXTDISK EQU       *                   COME HERE TO JUMP TO OUR
*    NEXT ACCESSED DISK.  THIS ROUTINE RETURNS A 'FILE NOT FOUND'
*    CONDITION CODE WHEN IT RUNS OUT OF DISKS TO CHECK.
*
         L         10,ADTPTR           GRAB NEXT BLOCK IN CHAIN
         LTR       10,10               MAKE SURE THIS ISN'T THE END
         BNZ       CHECKDSK            IT'S THERE, GO LOOK AT IT.
         LA        15,4                SORRY, NO MORE
         L         1,PABFST            GET ADDRESS OF COPYED FST
         MVC       0(4,1),=X'FF000000' RETURN A NULL AS FST
         L         1,PABADT            ADDRESS FOR ADT
         MVC       0(4,1),=X'FF000000' DITTO FOR ADT
         B         DONE                BYE.
CHECKDSK EQU       *                   MAKE SURE DISK IS ACCESSED
*    AND MATCHES COPYED FM BEFORE GIVING IT TO ANYONE
         TM        ADTFLG1,ADTFRO+ADTFRW   IS IT A CMS DISK?
         BZ        NEXTDISK            NO, TRY NEXT ONE
         MVC       STRINGL1(2),=H'1'   LENGTH FOR MODE IS 1
         MVC       STRINGL2(2),=H'1'   DITTO
         MVC       STRINGT1(1),COPYFM  COPY HIS FM
         MVC       STRINGT2(1),ADTM    COPY DISK'S MODE
         LA        1,WILDPAB           POINT TO PARMS
         L         15,=V(WILD)         I HATE TYPING THIS
         BALR      14,15               CALL HIM
         LTR       15,15               CHECK CC
         BNZ       NEXTDISK            DIDN'T WORK, TRY ANOTHER
         L         1,ADTFDA            GRAB HYPERBLOCK ADDRESS
         USING     DCHSECT,1           TELL ASSEMBLER
         ST        1,HYPE              SAVE HYPERBLOCK START
         LA        8,DCHDATA           FIRST FST
         L         2,DCHDWSIZ          GET SIZE IN DWORDS
         SLL       2,3                 CONVERT TO BYTES
         LA        2,DCHSECT(2)        COMPUTE LENGTH OF HYPERBLK
         ST        2,HYPEND            SAVE END
         B         MTCHFILE            AND KEEP TRYING.
         DROP      1                   KLUNK
DONE     EQU       *                   RESTORE EVERYTHING BUT 15, RET
         L         13,4(13)           OLD SAVE AREA
         L         14,12(13)           RESTORE R14
         LM        0,12,20(13)         NOW THE REST
         BR        14                  HOME, JAMES!
* DATA AREA
NEXTFSTA CSECT
SAVEAREA DS        18F                 SAVE AREA FOR GUY DOWN THERE
WILDPAB  DC        A(STRINGL1,STRINGL2,WILDCHAR)
STRINGL1 DS        H
STRINGT1 DS        CL8
STRINGL2 DS        H
STRINGT2 DS        CL8
WILDCHAR DC        C'*%'               STANDARD WILDCARD CHARS
HYPE     DS        A                   ADDRESS OF CURRENT HYPERBLK
HYPEND   DS        A                   END OF CURRENT HYPERBLK
PFNL     DS        H                   LENGTH OF COPYED FILENAME
PFTL     DS        H                     "     "   "    FILEMODE
COPYFI   DS        CL18                FOR FILENAME,FILETYPE,FM
         ORG       COPYFI              FOR OVERLAY
COPYFN   DS        CL8
COPYFT   DS        CL8
COPYFM   DS        CL2
         ORG
NSPC     DC        256X'00'            ALLOW EVERYTHING
         ORG       NSPC+C' '           EXCEPT
         DC        X'01'               SPACES
         ORG
PAB      DSECT
PABFN    DS        A                   POINTER TO FN,FT,FM
PABADT   DS        A                   ADDRESS OF ADT TO START WITH
PABFST   DS        A                   POINTER TO ADDR OF FST TO START
PASSFI   DSECT
PASSFN   DS        CL8                 THE NAME
PASSFT   DS        CL8                 THE TYPE
PASSFM   DS        CL2                 AND THE MODE
         NUCON     ,                   NUCLEUS CONSTANTS
         FSTB      ,         THE OLD EXTENDED FILE STATUS TABLE
         ADT       ,         THE PROVERBIAL ACTIVE DISK TABLE
         DCH       ,         DATA CONTROL HYBERBLOCK (DON'T LOOK AT US)
         END

