      SUBROUTINE W3AI41(KFLD,KOUT,KLEN,KNUM,KOFF)
C$$$  SUBROUTINE DOCUMENTATION BLOCK ***
C
C SUBR: W3AI41                 CONSTANT SIZE BINARY STRING UNPACKER
C   AUTHOR: ALLARD, R.         ORG: W342          DATE:    APR 80
C
C ABSTRACT: UNPACK CONSECUTIVE BINARY STRINGS OF THE SAME SIZE FROM
C   ONE USER SUPPLIED ARRAY AND STORE THEM IN THE SAME ORDER RIGHT
C   ALIGNED IN ANOTHER ARRAY. W3AI41 IS THE REVERSE OF W3AI40.
C
C PROGRAM HISTORY LOG:
C   80-04-01  R.ALLARD (ORIGINAL AUTHOR)  ASMEMBLER LANGUAGE VERSION.
C   84-07-05  R.E.JONES  RECOMPILED FOR NAS-9050
C   88-07-05  R.E.JONES  WROTE FORTRAN VERSION OF W3AI41 TO UNPACK
C                        VARIABLE SIZE BINARY STRINGS, ADDED CODE TO
C                        REVERSE ORDER OF BYTES FOR PC OR VAX.
C   90-06-12  R.E.JONES  CHANGE TO SUN FORTRAN 1.3
C   91-03-07  R.E.JONES  CHANGE TO SILICON GRAPHICS FORTRAN 3.O
C
C USAGE: CALL W3AI41 (KFLD,KOUT,KLEN,KNUM,KOFF)
C
C   INPUT:
C     KFLD   - INTEGER*4 ARRAY CONTINING BINARY STRING(S)
C     KLEN   - INTEGER*4 NUMBER OF BITS PER STRING (0 < KLEN < 33)
C     KNUM   - INTEGER*4 NUMBER OF STRINGS TO UNPACK. THIS VALUE MUST
*              NOT EXCEED THE DIMENSION OF 'KOUT'.
C     KOFF   - INTEGER*4 NUMBER SPECIFYING THE BIT OFFSET OF THE
C              FIRST STRING 'KFLD'. THE OFFSET VALUE IS RESET TO
C              INCLUDE THE LOW ORDER BIT OF THE LAST STRING UNPACKED
C              ('KOFF' > 0 )
C   OUTPUT:
C     KOUT   - INTEGER*4 ARRAY HOLDING UNPACKED STRING(S)
C
C   EXIT STATES:
C     ERROR - 'KOFF' < 0 IF 'KLEN' HAS AN ILLEGAL VALUE OR 'KNUM' < 1
C             THEN 'KOUT' HAS NO STRINGS STORED.
C
C   EXTERNAL REFERENCES: NONE
C
C REMARKS:  THIS SUBROUTINE SHOULD BE WRITTEN IN ASSEMBLER LANGUAGE.
C   THE FORTRAN VERSION RUNS TWO OR THREE TIMES SLOWER THAN THE ASEMBLER
C   VERSION. THE FORTRAN VERSION CAN BE CONVERTED TO RUN ON OTHER
C   COMPUTERS WITH A FEW CHANGES. THE BIT MANIPULATION FUNCTIONS ARE THE
C   SAME IN IBM370 VS FORTRAN, MICROSOFT FORTRAN 5.0, VAX FORTRAN.
C   MOST MODERN FORTRAN COMPILER HAVE AND, OR, SHIFT FUNCTIONS. IF YOU
C   ARE RUNNING ON A PC, VAX, INTERGRAPH, AND YOUR INPUT WAS MADE ON A
C   IBM370, APOLLO, SUN, H.P, OR BIG ENDIAN COMPUTER. YOU MAY HAVE TO
C   CHANGE THIS SUBROUTINE TO REVERSE THE ORDER OF BYTES IN AN INTEGER
C   WORD. YOU COULD ALSO CALL SWAP32 OR NCAR SUBROUTINE SWAP4 TO REVERSE
C   THE ORDER OF BYTES BEFORE USING THIS SUBROUTINE.
C
C ATTRIBUTES:
C   LANGUAGE: SiliconGraphics 3.3 FORTRAN 77
C   MACHINE:  SiliconGraphics IRIS-4D/25
C
C$$$
C
      INTEGER   KFLD(*)
      INTEGER   KOUT(*)
      INTEGER   BITSET
      INTEGER   OFFSET
      INTEGER   WRDSET
C
      OFFSET = KOFF
      IF (OFFSET.LT.0) RETURN
      IF (KLEN.GT.32.OR.KLEN.LT.1) THEN
        KOFF = -1
        RETURN
      ENDIF
C
      IF (KNUM.LT.1) THEN
        KOFF = -1
        RETURN
      ENDIF
C
        JCOUNT  = 32 - KLEN
        LENGTH  = KLEN
C
      DO 100  I = 1,KNUM
        WRDSET  = ISHFT(OFFSET,-5)
        BITSET  = MOD(OFFSET,32)
        ITEMP   = KFLD(WRDSET+1)
        NTEMP   = KFLD(WRDSET+2)
        ITEMP   = ISHFT(ITEMP,BITSET)
        IF (BITSET.EQ.0) NTEMP = 0
        NTEMP   = ISHFT(NTEMP,-32+BITSET)
        KOUT(I) = ISHFT(IOR(ITEMP,NTEMP),-JCOUNT)
        OFFSET  = OFFSET + LENGTH
 100  CONTINUE
        KOFF = OFFSET
      RETURN
      END
