      SUBROUTINE TABBD (OPCODE, BUFFER, IBDRNO, BDKOLS, BDNUMV, NUMIF,
     *   NUMFRQ, NUMPOL, TIME, SOURID, SUBA, ANT1, ANT2, FREQID,
     *   BNDPAS, IERR)
C-----------------------------------------------------------------------
C! Does I/O to BLCHN/BLPCL bandpass (BD) table opened by BDINI
C# EXT-util UV Calibration Spectral
C-----------------------------------------------------------------------
C;  Copyright (C) 2009, 2013, 2015, 2023
C;  Associated Universities, Inc. Washington DC, USA.
C;
C;  This program is free software; you can redistribute it and/or
C;  modify it under the terms of the GNU General Public License as
C;  published by the Free Software Foundation; either version 2 of
C;  the License, or (at your option) any later version.
C;
C;  This program is distributed in the hope that it will be useful,
C;  but WITHOUT ANY WARRANTY; without even the implied warranty of
C;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
C;  GNU General Public License for more details.
C;
C;  You should have received a copy of the GNU General Public
C;  License along with this program; if not, write to the Free
C;  Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
C;  MA 02139, USA.
C;
C;  Correspondence concerning AIPS should be addressed as follows:
C;         Internet email: aipsmail@nrao.edu.
C;         Postal address: AIPS Project Office
C;                         National Radio Astronomy Observatory
C;                         520 Edgemont Road
C;                         Charlottesville, VA 22903-2475 USA
C-----------------------------------------------------------------------
C   Does I/O to bandpass (BD) extention tables. Usually used after
C   setup by BDINI.
C   Inputs:
C      OPCODE   C*4      Operation code:
C                        'READ' = read entry from table.
C                        'WRIT' = write entry in table.
C                        'CLOS' = close file, flush on write
C      BUFFER   I(512)   I/O buffer and related storage, also defines
C                        file if open. Should have been returned by
C                        BDINI or TABINI.
C      IBDRNO   I        Next entry number to read or write.
C      BDKOLS   I(MAXBDC) The column pointer array in order,
C                        TIME, SOURID, SUBARRAY, ANTENNA1, ANTENNA2,
C                        FREQID, REAL1, IMAG1,
C                        Following used if 2 polarizations per IF
C                        REAL2, IMAG2.
C      BDNUMV   I(MAXBDC) Element count in each column.
C      NUMIF    I        Number of IF's
C      NUMFRQ   I        Number of chns
C      NUMPOL   I        Number of polarizations per IF.
C   Input/output: (written to or read from baseline file)
C      TIME    R(2)     Time range of record (Days)
C      SOURID  I        Source ID number.
C      SUBA    I        Subarray number.
C      ANT     I        Antenna number.
C      FREQID  I        Freq. id number
C      BNDPAS  C(n,m,p) Complex bandpass: m IFS; n channels; p polns
C   Output:
C      IBDRNO    I      Next solution number.
C      IERR      I      Error code, 0=>OK else TABIO error.
C                       Note: -3=> all flagged
C-----------------------------------------------------------------------
      INTEGER   MAXBDC
      PARAMETER (MAXBDC = 14)
C
      CHARACTER OPCODE*4
      INTEGER   BUFFER(*), IBDRNO, BDKOLS(MAXBDC), BDNUMV(MAXBDC),
     *   NUMIF, NUMFRQ, NUMPOL, SOURID, SUBA, ANT1, ANT2, FREQID, IERR
      REAL      TIME(2), BNDPAS(*)
C
      INCLUDE 'INCS:PUVD.INC'
      INTEGER   XBDRSZ
      PARAMETER (XBDRSZ = 6 + 8*MAXCIF)
C
      INTEGER   RECI(XBDRSZ), KOLS(MAXBDC), TIMKOL, SOUKOL, SUBKOL, J,
     *   ANT1KL, ANT2KL, FRQKOL, LOOP, NDATA, BDCNT, INDX, NNDX, RKOL,
     *   IKOL
      REAL      RECORD(XBDRSZ)
      DOUBLE PRECISION RECD(XBDRSZ/2)
      INCLUDE 'INCS:DMSG.INC'
      INCLUDE 'INCS:DDCH.INC'
      SAVE RECORD
      EQUIVALENCE (KOLS(1), TIMKOL), (KOLS(2), SOUKOL),
     *   (KOLS(3), SUBKOL), (KOLS(4), ANT1KL), (KOLS(5), ANT2KL),
     *   (KOLS(6), FRQKOL)
      EQUIVALENCE (RECD, RECORD, RECI)
C-----------------------------------------------------------------------
      BDCNT = 0
C                                       Close
      IF (OPCODE.EQ.'CLOS') THEN
         CALL TABIO ('CLOS', 0, IBDRNO, RECORD, BUFFER, IERR)
         IF (IERR.GT.0) GO TO 980
         GO TO 999
         END IF
C                                       Check sizes
      NNDX = NUMPOL * NUMFRQ * NUMIF
      IF (NNDX.GT.MAXCIF) THEN
         IERR = 1
         MSGTXT = 'TABBD: RECORDS TOO BIG FOR BUFFERS'
         GO TO 985
         END IF
      IF (NNDX.LE.0) THEN
         IERR = 1
         MSGTXT = 'TABBD: ZERO SIZE DATA REQUESTED'
         GO TO 985
         END IF
      IF (NUMPOL.GT.4) THEN
         IERR = 1
         MSGTXT = 'TABBD: > 4 POLARIZATIONS IN BANDPASS TABLE!'
         GO TO 985
         END IF
C                                       Set pointers
      NDATA = MAXBDC
      CALL COPY (NDATA, BDKOLS, KOLS)
      NNDX = NUMFRQ * NUMIF
C                                       If write fill RECORD
      IF (OPCODE.NE.'READ') THEN
         RECORD(TIMKOL) = TIME(1)
         RECORD(TIMKOL+1) = TIME(2)
         RECI(SOUKOL) = SOURID
         RECI(SUBKOL) = SUBA
         RECI(ANT1KL) = ANT1
         RECI(ANT2KL) = ANT2
         IF (FRQKOL.GT.0) RECI(FRQKOL) = FREQID
C                                       All polarizations
         INDX = 0
         DO 30 J = 1,NUMPOL
            RKOL = KOLS(5+2*J)
            IKOL = KOLS(6+2*J)
            DO 20 LOOP = 1,NNDX
               INDX = INDX + 1
               RECORD(RKOL) = BNDPAS(INDX)
               INDX = INDX + 1
               RECORD(IKOL) = BNDPAS(INDX)
               RKOL = RKOL + 1
               IKOL = IKOL + 1
 20            CONTINUE
 30         CONTINUE
         END IF
C                                       Process record.
      CALL TABIO (OPCODE, 0, IBDRNO, RECORD, BUFFER, IERR)
      IBDRNO = IBDRNO + 1
      IF (IERR.GT.0) GO TO 980
C                                       If READ pick data from RECORD.
      IF (OPCODE.EQ.'READ') THEN
         TIME(1) = RECORD(TIMKOL)
         TIME(2) = RECORD(TIMKOL+1)
         SOURID = RECI(SOUKOL)
         SUBA   = RECI(SUBKOL)
         ANT1    = RECI(ANT1KL)
         ANT2    = RECI(ANT2KL)
         IF (FRQKOL.LE.0) THEN
            FREQID = 1
         ELSE
            FREQID = RECI(FRQKOL)
            END IF
C                                       First polarization
         INDX = 0
         DO 90 J = 1,NUMPOL
            RKOL = KOLS(5+2*J)
            IKOL = KOLS(6+2*J)
            DO 80 LOOP = 1,NNDX
               INDX = INDX + 1
               BNDPAS(INDX) = RECORD(RKOL)
               INDX = INDX + 1
               BNDPAS(INDX) = RECORD(IKOL)
               IF ((RECORD(RKOL).EQ.FBLANK) .OR.
     *            (RECORD(IKOL).EQ.FBLANK)) BDCNT = BDCNT + 1
               RKOL = RKOL + 1
               IKOL = IKOL + 1
 80            CONTINUE
 90         CONTINUE
         END IF
      IF (BDCNT.EQ.(NUMPOL*NUMIF*NUMFRQ)) IERR = -3
      GO TO 999
C                                       Error
 980  WRITE (MSGTXT,1980) IERR
C
 985  CALL MSGWRT (8)
C
 999  RETURN
C-----------------------------------------------------------------------
 1980 FORMAT ('TABBD: TABIO ERROR',I3)
      END
