/* dtslc.c
   L. Stewart April 30, 1983  2:01 PM, created
   L. Stewart April 30, 1983  2:03 PM, new EtherHost
 */

#include <Lark.h>
#include <Ec.h>
#include <Env.h>
#include <Queue.h>
#include <Pup.h>

struct ccb {
  char cmda;
  char *addra;
  char counta;
  char stata;
  };

/* Runtime */
extern InByte();
extern Swab();

/* Timer package */
extern SetTmr();
extern TmrExp();

/* Ethernet machine language */
extern SLCInit();
extern SLTStart();
extern SLRStart();

/* Receive packets */

static struct ccb rxccb;
static struct PBI *rxPBI;
static int rxLength;
static int rxTmr;

SStartRx(pbi, length)
  struct PBI *pbi;
  int length;
  {
  rxPBI = pbi;
  rxLength = length;
  rxccb.cmda = 0x00;
  rxccb.addra = rxPBI->pup;
  rxccb.addra = rxccb.addra - 4;
  rxccb.counta = (-rxLength) & 0x00ff;
  rxccb.stata = 0;
  SLRStart(&rxccb);
  SetTmr(10000, &rxTmr);
  };

struct PBI *SCheckRx()
  {
  struct EtherEncapsulation *ee;
  int temp;
  if (rxccb.stata & 0x80) {
    if (rxccb.stata == 0x88) {
      temp = (int) rxPBI->pup;
      temp -= 4;
      ee = (struct EtherEncapsulation *) temp;
      if (ee->type == 2) return(rxPBI);  /* Swabbed typePup */
      };
    SStartRx(rxPBI, rxLength)
    };
  if (TmrExp(&rxTmr)) {
    SLCReset();  /* violent ! */
    SStartRx(rxPBI, rxLength)
    return (0);
    };
  return (0);
  };

/* Utility */

int EtherHost()
  {
  return (FetchW(0xFFFE));
  };

SLCReset()
  {
  SLCInit(EtherHost());
  };

/* Transmit packets */

static struct ccb txccb;
static int txTmr;

SStartTx(pbi)
  struct PBI *pbi;
  {
  int len;
  len = Swab(pbi->pup->length);
  len = (len + 5) & 0x0fffe;
  txccb.cmda = 0x50;
  txccb.addra = pbi->pup;
  txccb.addra = txccb.addra - 4;
  txccb.counta = len & 0x00ff;
  txccb.stata = 0;
  SLTStart(&txccb);
  SetTmr(200, &txTmr);
  };

SCheckTx()
  {
  if (txccb.stata & 0x80) return(true);
  if (TmrExp(&txTmr)) {
    SLCReset();  /* violent ! */
    return(true);
    };
  return(false);
  };