/* test2001.c   January 3, 1983  2:09 PM   */

#include "lark.h"
#include "Encrypt.h"
#include "env.h"
#include "queue.h"

extern int Encrypt(), crypt(), encend(), Chav(), wf();
extern int getchar(), putchar();
extern int inbyte();
extern int outbyte();

extern char DesTriples;
extern int NumTriples;

static int ifastb;
struct Queue iwaitq;
static int triple;
static char ca[8];
static char key[8];
static char plain[160];
static char cypher[160];
static char res[160];

static char sk[8];
static char sp[8];
static char sc[8];
static char tb[8];
static char *kp;
static char *dp;
static char *cp;
static struct ECB iecb[10];

main()
  {
  char c;
  int i;
  InitOS();
  wf("\r2001 test, ? for help.\r");
  for (i=0; i<8; i++) key[i] = 0x01;
  for (i=0; i<160; i++) plain[i] = i;
  kp = &DesTriples;
  dp = &DesTriples+8;
  cp = &DesTriples+16;
  triple = 0;
  initiecb();
  for (;;) {
      c = getchar() & 0177;
      switch (c) {
        case 'q': { wf("\rQuit!\r"); return; };
        case '?': { help(); break; };
        case 'o': { once(); break; };
        case 's': { fast(); break; };
        case 't': { itrip(); break; };
        case 'p': { sdma(); break; };
	case '1': { ionce(); break; };
        case '2': { ifast(); break; };
        default: wf("\r unknown command\r");
        };
 };  /* end of forever loop */
 };

static initiecb()
  {
  int i;
  for (i=0; i<10; i += 1) {
    iecb[i].kp = key;
    iecb[i].srcp = plain;
    iecb[i].dstp = cypher;
    };
  for (i=0; i<10; i += 1) {
    iecb[i].count = 160;
    iecb[i].encrypt = true;
    iecb[i].proc = 0;
    iecb[i].item = i;
    };
  };

static islowproc(p)
  int *p;
  {
  *p = true;
  };

static ionce()
  {
  int flag;
  flag = false;
  iecb[0].proc = (int) &islowproc;
  iecb[0].item = (int) &flag;
  Encrypt(&iecb[0]);
  while(!flag && !Chav()) Block();
  getchar();
  wfcr();
  };

static ifastproc(n)
  int n;
  {
  Enqueue(&iwaitq, &iecb[n]);
  };

static ifast()
  {
  struct ECB *p;
  int i, count;
  initiecb();
  InitQueue(&iwaitq);
  ifastb = true;
  for (i=0; i<10; i+=1) {
    iecb[i].item = i;
    iecb[i].proc = (int) &ifastproc;
    Encrypt(&iecb[i]);
    };
  for (;;) {
    if (Chav()) break;
    p = Dequeue(&iwaitq);
    if (p) {
      Encrypt(p);
      count += 1;
      if (count > 100) {
        putchar('.');
        count = 0;
        };
      };
    };
  getchar();
  wfcr();
  };

static itrip()
  {
  triple = ( triple + 1 ) % NumTriples;
  wf1("triple = %d\n", triple);
  };

static fast()
  {
  wf("\rNon-DMA test, type char to stop\r");
  while (!Chav()) nodma();
  getchar();
  };

static once()
  {
  nodma();
  wf("once\r");
  };

static nodma()
  {
  int i, idx, go, once, res;
  for (i=0;i<(NumTriples*2);i++) {
    idx = (i % NumTriples) * 24;
    if (i<=6) res = descypher(1, kp+idx, dp+idx, cp+idx);
    else res = descypher(0, kp+idx, cp+idx, dp+idx);
    switch (res) {
      case 1: wf(" KR "); break;
      case 2: wf(" KPE "); break;
      case 3: wf(" DIR "); break;
      case 4: wf(" DOR "); break;
      case 5: wf(" err "); break;
      default: putchar('.'); break;
      };
    };
  };

static help()
  {
  wf("\rq: quit, o: nodma, ?: help\r");
  wf("p: print diffs, s: no-dma fast\r");
  wf("1: interrupt once, 2: interrupt fast\r");
  };

static sdma()
  {
  int i, idx, flag;
  struct ECB sbe, sbd;
  idx = (triple % NumTriples) * 24;
  triple = (triple + 1) % NumTriples;
  for (i = 0; i < 8; i += 1) {
    sk[i] = kp[idx+i];
    sp[i] = dp[idx+i];
    sc[i] = cp[idx+i];
    };
  sbe.kp = sk;
  sbe.srcp = sp;
  sbe.dstp = tb;
  sbe.count = 8;
  sbe.encrypt = true;
  sbe.proc = (int) &islowproc;
  sbe.item = (int) &flag;
  sbd.kp = sk;
  sbd.srcp = sc;
  sbd.dstp = tb;
  sbd.count = 8;
  sbd.encrypt = false;
  sbd.proc = (int) &islowproc;
  sbd.item = (int) &flag;
  flag = false;
  Encrypt(&sbe);
  while (!flag && !Chav()) Block();
  for (i = 0; i < 8; i += 1) {
    if (sc[i] != tb[i]) {
      wf("encrypt was: ");
      printary(tb);
      wf("should be: ");
      printary(sc);
      wf("\r");
      break;
      };
    };
  flag = false;
  Encrypt(&sbe);
  while (!flag && !Chav()) Block();
  for (i = 0; i < 8; i += 1) {
    if (sc[i] != tb[i]) {
      wf("decrypt was: ");
      printary(tb);
      wf("should be: ");
      printary(sp);
      wf("\r");
      break;
      };
    };
  };

static printary(p)
  char *p;
  {
  int i;
  for (i=0; i<8; i+=1) {
    wf1("%02x ", p[i] & 0xff);
    };
  };

/* programmed encryption */
/* encrypts and checks against cyphertext */
static descypher(enc, k, p, c)
  int enc;
  char *k, *p, *c;
  {
  int i, ecmd;
  if (enc) ecmd = 0;
  else ecmd = 8;
  outbyte(encctl,ecmd);  /* reset */
  outbyte(encctl,ecmd+2);  /* activate */
  if ((inbyte(encctl)&0x10) == 0) return (1);
  putblk(encdata, k, 8);
  if ((inbyte(encctl)&0x20) != 0) return (2);
  if ((inbyte(encctl)&0x40) == 0) return (3);
  putblk(encdata, p, 8);
  /* wait a decent interval */
  for (i=0;i<10;i++);
  if ((inbyte(encctl)&0x80) == 0) return (4);
  getblk(encdata, ca, 8);
  for (i=0;i<8;i++) {
    if (ca[i] != *c++) return(5);
    };
  return (0);
  };

static putblk(port,data,count)
  int port;
  char *data;
  int count;
  {
  while(count--) outbyte(port, *data++);
  };

static getblk(port,data,count)
  int port;
  char *data;
  int count;
  {
  while(count--) { *data++ = inbyte(port); };
  };

/*
  November 2, 1982  11:02 AM bring up to date
 */