
/*
 *
  Copyright (c) Eicon Networks, 2002.
 *
  This source file is supplied for the use with
  Eicon Networks range of DIVA Server Adapters.
 *
  Eicon File Revision :    2.1
 *
  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2, or (at your option)
  any later version.
 *
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY OF ANY KIND WHATSOEVER INCLUDING ANY
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the GNU General Public License for more details.
 *
  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */
#include "platform.h"
#if defined(DIVA_ISTREAM) /* { */
#include "pc.h"
#include "pr_pc.h"
#include "di_defs.h"
#include "divasync.h"
#include "di.h"
#if !defined USE_EXTENDED_DEBUGS
  #include "dimaint.h"
#else
  #define dprintf
#endif
#include "dfifo.h"
int diva_istream_write (void* context,
             int   Id,
              void* data,
             int length,
             int final,
            byte usr1,
            byte usr2);
int diva_istream_read (void* context,
            int Id,
            void* data,
            int max_length,
            int* final,
            byte* usr1,
            byte* usr2);
/* -------------------------------------------------------------------
  Does provide iStream interface to the client
   ------------------------------------------------------------------- */
void diva_xdi_provide_istream_info (ADAPTER* a,
                  diva_xdi_stream_interface_t* pi) {
  pi->provided_service = 0;
}
/* ------------------------------------------------------------------
  Does write the data from caller's buffer to the card's
  stream interface.
  If synchronous service was requested, then function
  does return amount of data written to stream.
  'final' does indicate that piece of data to be written is
  final part of frame (necessary only by structured datatransfer)
  return  0 if zero lengh packet was written
  return -1 if stream is full
  ------------------------------------------------------------------ */
int diva_istream_write (void* context,
                int   Id,
                  void* data,
                 int length,
                 int final,
                byte usr1,
                byte usr2) {
 ADAPTER* a = (ADAPTER*)context;
 int written = 0, to_write = -1;
 char tmp[4];
 byte* data_ptr = (byte*)data;
 for (;;) {
  a->ram_in_dw (a,
#ifdef PLATFORM_GT_32BIT
         ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
#else
         (void*)(a->tx_stream[Id] + a->tx_pos[Id]),
#endif
                  (dword*)&tmp[0],
         1);
  if (tmp[0] & DIVA_DFIFO_READY) { /* No free blocks more */
   if (to_write < 0)
    return (-1); /* was not able to write       */
   break;     /* only part of message was written */
  }
  to_write = min(length, DIVA_DFIFO_DATA_SZ);
  if (to_write) {
   a->ram_out_buffer (a,
#ifdef PLATFORM_GT_32BIT
            ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]+4),
#else
              (void*)(a->tx_stream[Id] + a->tx_pos[Id] + 4),
#endif
                         data_ptr,
             (word)to_write);
   length  -= to_write;
   written  += to_write;
   data_ptr += to_write;
  }
  tmp[1] = (char)to_write;
  tmp[0] = (tmp[0] & DIVA_DFIFO_WRAP) |
       DIVA_DFIFO_READY |
       ((!length && final) ? DIVA_DFIFO_LAST : 0);
  if (tmp[0] & DIVA_DFIFO_LAST) {
   tmp[2] = usr1;
   tmp[3] = usr2;
  }
    a->ram_out_dw (a,
#ifdef PLATFORM_GT_32BIT
         ULongToPtr(a->tx_stream[Id] + a->tx_pos[Id]),
#else
           (void*)(a->tx_stream[Id] + a->tx_pos[Id]),
#endif
                   (dword*)&tmp[0],
          1);
  if (tmp[0] & DIVA_DFIFO_WRAP) {
   a->tx_pos[Id]  = 0;
  } else {
   a->tx_pos[Id] += DIVA_DFIFO_STEP;
  }
  if (!length) {
   break;
  }
 }
 return (written);
}
/* -------------------------------------------------------------------
  In case of SYNCRONOUS service:
  Does write data from stream in caller's buffer.
  Does return amount of data written to buffer
  Final flag is set on return if last part of structured frame
  was received
  return 0  if zero packet was received
  return -1 if stream is empty
    return -2 if read buffer does not profide sufficient space
              to accommodate entire segment
  max_length should be at least 68 bytes
  ------------------------------------------------------------------- */
int diva_istream_read (void* context,
                int Id,
                void* data,
                int max_length,
                int* final,
               byte* usr1,
               byte* usr2) {
 ADAPTER* a = (ADAPTER*)context;
 int read = 0, to_read = -1;
 char tmp[4];
 byte* data_ptr = (byte*)data;
 *final = 0;
 for (;;) {
  a->ram_in_dw (a,
#ifdef PLATFORM_GT_32BIT
         ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
#else
         (void*)(a->rx_stream[Id] + a->rx_pos[Id]),
#endif
                  (dword*)&tmp[0],
         1);
  if (tmp[1] > max_length) {
   if (to_read < 0)
    return (-2); /* was not able to read */
   break;
    }
  if (!(tmp[0] & DIVA_DFIFO_READY)) {
   if (to_read < 0)
    return (-1); /* was not able to read */
   break;
  }
  to_read = min(max_length, (int)tmp[1]);
  if (to_read) {
   a->ram_in_buffer(a,
#ifdef PLATFORM_GT_32BIT
           ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id] + 4),
#else
            (void*)(a->rx_stream[Id] + a->rx_pos[Id] + 4),
#endif
                       data_ptr,
            (word)to_read);
   max_length -= to_read;
   read     += to_read;
   data_ptr  += to_read;
  }
  if (tmp[0] & DIVA_DFIFO_LAST) {
   *final = 1;
  }
  tmp[0] &= DIVA_DFIFO_WRAP;
    a->ram_out_dw(a,
#ifdef PLATFORM_GT_32BIT
         ULongToPtr(a->rx_stream[Id] + a->rx_pos[Id]),
#else
         (void*)(a->rx_stream[Id] + a->rx_pos[Id]),
#endif
         (dword*)&tmp[0],
         1);
  if (tmp[0] & DIVA_DFIFO_WRAP) {
   a->rx_pos[Id]  = 0;
  } else {
   a->rx_pos[Id] += DIVA_DFIFO_STEP;
  }
  if (*final) {
   if (usr1)
    *usr1 = tmp[2];
   if (usr2)
    *usr2 = tmp[3];
   break;
  }
 }
 return (read);
}
/* ---------------------------------------------------------------------
  Does check if one of streams had caused interrupt and does
  wake up corresponding application
   --------------------------------------------------------------------- */
void pr_stream (ADAPTER * a) {
}
#endif /* } */
