/* tiport.c - Low level communications routines for TI85 on       */
/*            $4 serial link.  Some bit repositioning              */
/*            to allow use of IBM link routines.                */
/* send() and recv() are based on the send() and recvbyt()        */
/* routines contained in Per Finander's tiproto.txt file          */
/* Shawn D'Alimonte May 17, 1997                                  */

#include "tiport.h"
#include <stdio.h>

/* For timeout routines */
#include <time.h>
static clock_t start_time;
#define TIMEOUT 60

/* reset timeout counter */
void timereset(void)
{
  start_time=clock();
}


/* test if the transfer has timed out */
void timetest(void) 
{
  if((clock()-start_time)/CLOCKS_PER_SEC>TIMEOUT)
    {
      printf("Timeout!  Aborting.\n");
      abort();
    }
}

/* Setup access to CIA's for parallel port */
#include <hardware/cia.h>
extern struct CIA ciaa,ciab;

/* val: bit0 = DTR. bit1=RTS */
void  setport(UBYTE val)
{
  UBYTE val2 =(3-val)&0x03;
 ciab.ciapra = (val2&0x01)<<7|(val2&0x02)<<5;

#ifdef DEBUG
  printf("setport sending %x\n",val);
#endif
  
}

/* Returns values of CTS and DSR lines */
/* bit0=cts, bit1=dsr */
/* Amiga CTS = bit4, DSR = bit3*/
UBYTE getport(void)
{
  UBYTE val; 
  val = ciab.ciapra & 0x18;
  
#ifdef DEBUG
  printf("getport: port contains %x\n", val);
#endif
  
  val = (val & 0x10)>>4|(val & 0x08)>>2; 
  val = 3-val;
#ifdef DEBUG
  printf("getport returning %x\n",val);
#endif
  return val;
}

/* Initialize port */
void initport(void)
{
#ifdef DEBUG
  printf("Initializing port\n");
#endif
  ciaa.ciaddrb = 0xc0;
  setport(3);                         /* Keep calc from slowing  */
}

void  send(UBYTE b)
{
  UBYTE bits;
#ifdef DBG
    printf("C: %2x\n",b);
#endif  
  timereset();
  for (bits=1;bits<=8;bits++)
    {
      if (b&1) 
	setport(2);
      else
	setport(1);
      while(getport() != 0) timetest();
      timereset();
      setport(3);
      while (getport() !=3) timetest();
      b>>=1;
    }
}

/* Sends a byte to the TI85 */
UBYTE recv(void)         
{
  UBYTE curbit=1;
  UBYTE byt=0,bits,x;
  
  timereset();
  for(bits=1; bits<=8;bits++)
    {
      while((x=getport()) == 3) timetest();;
#ifdef DEBUG
	  printf("recv: Waiting for bit\n");
#endif
      if (x==1)
	{
#ifdef DEBUG
	      printf("recv: Received a 1\n");
#endif
	      byt += curbit;
	      setport(1);
	      x=2;
	    }
	  else
	    {
#ifdef DEBUG
	      printf("recv: Received 0\n");
#endif
	      setport(2);
	      x=1;
	    }
      timereset();
      while ((getport() & x) == 0) timetest();
      setport(3);
      curbit <<=1;
    }
#ifdef DBG
  printf("T: %2x\n",byt);
#endif
  return byt;
}
  

