      SUBROUTINE REVERSE(IX,NBYTES)
C     * March 2003 - A.W. IRWIN 
C     * PURPOSE: BYTE REVERSE IX.
C     * THIS IS NORMALLY USED TO HELP SORT OUT ENDIAN ISSUES FOR
C     * 4-BYTE IX (NBYTES=4) OR 8-BYTE IX (NBYTES=8).
C     * IT IS THE CALLING ROUTINE'S RESPONSIBILITY TO CALL REVERSE WITH
C     * NBYTES=4 WHEN THE DEFAULT INTEGER PRECISION IS 4 BYTES, AND
C     * NBYTES=8 WHEN THE DEFAULT INTEGER PRECISION IS 8 BYTES.
C     * THIS VERSION USES MASKING AND SHIFTS TO DO THE BYTE SWAPS.
C     * INTEGER*1 WOULD BE MUCH QUICKER AND EASIER, BUT NOT ALL PLATFORMS
C     * SUPPORT BYTE-SIZED INTEGERS.
      IMPLICIT NONE
      INTEGER IX, NBYTES, IN, MASK8, MSHIFT(8), SSHIFT4(4), SSHIFT8(8)
      DATA MSHIFT/0, 8, 16, 24, 32, 40, 48, 56/
      DATA SSHIFT4/24, 8, -8, -24/
      DATA SSHIFT8/56, 40, 24, 8, -8, -24, -40, -56/
      MASK8 = IBITS(-1,0,8)
      IN = IX
      IF(NBYTES.EQ.4) THEN
        IX =
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(1))),SSHIFT4(1)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(2))),SSHIFT4(2)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(3))),SSHIFT4(3)),
     &         ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(4))),SSHIFT4(4))
     &    )))
      ELSEIF(NBYTES.EQ.8) THEN
        IX =
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(1))),SSHIFT8(1)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(2))),SSHIFT8(2)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(3))),SSHIFT8(3)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(4))),SSHIFT8(4)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(5))),SSHIFT8(5)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(6))),SSHIFT8(6)),
     &    IOR( ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(7))),SSHIFT8(7)),
     &         ISHFT(IAND(IN,ISHFT(MASK8,MSHIFT(8))),SSHIFT8(8))
     &    )))))))
      ELSE
        STOP 'REVERSE CALLED WITH INVALID NBYTES'
      ENDIF
      END
