/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

/* to investigate the teach pendant ... */

#include <stdio.h>

#define S0RCSR  (*(unsigned short *) 0176500)   /* Port 0 Recieve CSR	   */
#define S0RBUF  	  (*(char *) 0176502)   /* Port 0 Recieve Buffer   */
#define S0XCSR  (*(unsigned short *) 0176504)   /* Port 0 Transmit CSR     */
#define S0XBUF  	  (*(char *) 0176506)   /* Port 0 Transmit Buffer  */
 
#define S_READY		0200			/* Serial register ready  */
#define S_IEA		0100			/* Enable interrupts      */

union {
  short s;
  char c[2]; } getbyte;

extern short tick;
extern short (* onclk)();

#define NO 0
#define YES 1

char write_buf [2] = { 015, 0200 };
char read_buf [9];
int checksum_ok;
int clock_lock = NO;
int timeout = NO;
int miss = 0;

extern short teach_talk();

#define LSI1173

short teach_talk ()
{
 /* Talk to the teach pendant at interrupt time */
 
 int i;
 
 if (!clock_lock && miss == 0)
  {
    for (i = 0; i < 2; i++)
     { while (!(S0XCSR & S_READY))
          ;
       S0XBUF = (0xff & write_buf [i]);
     }
    checksum_ok = 0;
    for (i = 0; i < 9; i++)
     { while (!(S0RCSR & S_READY) && !timeout)
          ;
       read_buf [i] = (0xff & S0RBUF);
       checksum_ok += read_buf [i];
     }
  }
 if (miss > 0)
  { --miss;
  }
 
}

main ()
{
 short dummy;
 char cmd;

#ifdef LSI1173
 (* (unsigned short *) 0177546) |= 0100;	/* enable the clock */
#endif

 /* clear the input and output buffers */

#define CBREAK 0x01 
 ioctl (0, CBREAK, 0);

 /* start by clearing the line */
 
 S0RCSR = 0;
 S0XCSR = 0;

 while (S0RCSR & S_READY)
  { dummy = S0RBUF;
  }

 onclk = teach_talk;
 tick = 4;

 while (1)
  { printf ("\nTEACH> ");
    cmd = getchar();
    putchar ('\n');
    
    switch (cmd)
     { case '?':
	   { printf (" '?' : prints this message\n");
	     printf (" 'd' : displays the current packect\n");
	     printf (" 's' : set write buffer\n");
	     printf (" '+' : auto inc the last byte of the write string\n");
	     printf (" '*' : auto inc the first byte of the write string\n");
	     printf (" 'm' : miss some cycles\n");
	     printf ("\n");
	     break;
	   }
       case 'd':
	   { int i;

	     printf ("WRITE_BUFFER:   1  %02x   2  %02x\n",
	             (0xff & write_buf[0]), (0xff & write_buf[1]));
	     
	     printf ("READ BUFFER:\n");
	     for (i = 0; i < 8; i++)
	      { printf ("   %1d  %02x", i+1, (0xff & read_buf[i]));
		printf ("   ");
		print_binary (read_buf[i]);
		putchar ('\n');
	      }
	     
	     printf ("CHECKSUM: %d\n", checksum_ok);
	     break;
	   }
       case 's':
	   { int read1, read2;
	     
	     printf ("Enter new bytes 1 and 2 in hex > ");
	     scanf ("%x%x", &read1, &read2);
	     getchar ();

	     clock_lock = YES;
	     write_buf [0] = (0xff & read1);
	     write_buf [1] = (0xff & read2);
	     timeout = NO;
	     clock_lock = NO;

	     break;
	   }
       case '+':
	   { clock_lock = YES;
	     ++write_buf [1];
	     timeout = NO;
	     clock_lock = NO;
	     break;
	   }
       case '*':
	   { clock_lock = YES;
	     ++write_buf [0];
	     timeout = NO;
	     clock_lock = NO;
	     break;
	   }
       case 'm':
	   { printf ("Number of cycles to miss > ");
	     scanf ("%d", &miss);
	     break;
	   }
       default:
	   { printf ("Invalid command. Hit <?> for help\n");
	     break;
	   }
     }
  }
}

print_binary (value)
char value;
{
 int i;
 putchar (' ');
 for (i = 0; i < 8; i++)
  { if ((value >> (7-i)) & 0x1)
     { putchar ('1');
     }
    else
     { putchar ('.');
     }
  }
 putchar (' ');
}
 
 
	     
zexit (n)
{
 if (n == 9)
  { tick = 0;
    printf ("\nTimeout! Try another string!\n");
    timeout = YES;
    clock_lock = YES;
    onclk = teach_talk;
    tick = 4;
  }
 else
  { 
    printf ("Exit %d\n", n);
    halt();
  }
}
