/* test8259.c   Stewart, August 16, 1982  4:05 PM   */

/*  8259 is set up except that all interrupts are masked
 */

#include	"Lark.h"
#include	"Env.h"

extern int AlAInt;
extern int AlBInt;
extern int AlCInt;
extern int AlDInt;
extern int SIOInt;
extern int EncInt;
extern int SLRInt;
extern int SLTInt;
extern mySIOInt();

#define SLRMask 0x0001
#define SLTMask 0x0002
#define EncMask 0x0004
#define SIOMask 0x0008
#define AlAMask 0x0010
#define AlBMask 0x0020
#define AlCMask 0x0040
#define AlDMask 0x0080

int imask;
char leftover;
int any;
int count[8];
int bprint;

main()
  {
  char c;
  bprint = false;
  ZeroCount();
  IntOff();
  IntInit();
  InitHandlers();
  Init8274();
  wf("\r8259 test, ? for help.\r");
  IntMask(0);
  for (;;) {
      c = getchar() & 0177;
      switch (c) {
        case '0': DoSLRI(); break;
        case '1': DoSLTI(); break;
        case '2': DoEncI(); break;
        case '3': DoSIOI(); break;
        case '4': DoAlAI(); break;
        case '5': DoAlBI(); break;
        case '6': DoAlCI(); break;
        case '7': DoAlDI(); break;
        case '?': help(); break;
        case 'a': clearalog(); break;
        case 'e': echo(); break;
        case 'b': togbp(); break;
        case 'i': lion(); break;
        case 'o': lioff(); break;
        case 'm': gmask(); break;
        case 'p': pcounts(); break;
        case 'q': IntOff(); wf("\rQuit!\r"); return;
        case 'r': readregs(); break;
        case 's': Init8274(); break;
        case 'z': ZeroCount(); break;
        default: wf("\r unknown command");
        };
   wfcr();
 };  /* end of forever loop */
 };

togbp()
  {
  if (bprint) bprint = false;
  else bprint = true;
  wf1("bprint = %d\r", bprint);
  };

ZeroCount()
  {
  int i;
  wf("zero\r");
  for (i=0;i<8;i+=1) count[i] = 0;
  };

pcounts()
  {
  int i;
  for (i=0;i<8;i+=1) wf1("  %3d", count[i]);
  wfcr();
  };

clearalog()
  {
  outbyte(pioa, 0);
  outbyte(pioa, 0x0081);
  };

lion()
  {
  wf("\rinterrupts on");
  IntOn();
  };

lioff()
  {
  wf("\rinterrupts off");
  IntOff();
  };

help()
  {
  wf("[0..7] software interrupt\r");
  wf("a: clear alog, b: toggle printout\r");
  wf("e: echo\r");
  wf("i: int on, o: int off\r");
  wf("m: mask, p: print counts\r");
  wf("q: quit, r: 8259 regs, s: Init8274, z: zerocounts\r");
  wf("?: help\r");
  };

echo()
  {
  char c;
  int i;
  IntMask(SIOMask);
  for(;;) {
    if (avc(1)) {
      c = getc(1) & 0177;
      putchar(c);
      };
    if (chav()) {
      c = getchar() & 0177;
      if (c == 'q') break;
      if (uc(c)) { for (i=0;i<9;i+=1) putc(1, c); };
      putc(1, c);
      };
    };
  IntMask(0);
  };

readregs()
  {
  wf3("Mask: %02x, IRR: %02x, ISR: %02x\r", ReadIMask(), ReadIRR(), ReadISR());
  };

gmask()
  {
  wf("IMask: ");
  imask = gethex();
  wf1(" = %02x\r", imask);
  IntMask(imask);
  };

myAlAInt()
  {
  count[4] += 1;
  if (imask & AlAMask) {
    if (bprint) putchar('4');
    imask &= not(AlAMask);
    IntMask(imask);
    };
  };

myAlBInt()
  {
  count[5] += 1;
  if (imask & AlBMask) {
    if (bprint) putchar('5');
    imask &= not(AlBMask);
    IntMask(imask);
    };
  };

myAlCInt()
  {
  count[6] += 1;
  if (imask & AlCMask) {
    if (bprint) putchar('6');
    imask &= not(AlCMask);
    IntMask(imask);
    };
  };

myAlDInt()
  {
  count[7] += 1;
  if (imask & AlDMask) {
    if (bprint) putchar('7');
    imask &= not(AlDMask);
    IntMask(imask);
    };
  };
/*
mySIOInt()
  {
  count[3] += 1;
  if (bprint) putchar('3');
  imask &= not(SIOMask);
  IntMask(imask);
  };
*/
myEncInt()
  {
  count[2] += 1;
  if (bprint) putchar('2');
  imask &= not(EncMask);
  IntMask(imask);
  };

mySLTInt()
  {
  count[1] += 1;
  if (bprint) putchar('1');
  imask &= not(SLTMask);
  IntMask(imask);
  };

mySLRInt()
  {
  count[0] += 1;
  if (bprint) putchar('0');
  imask &= not(SLRMask);
  IntMask(imask);
  };

int not(x)
  int x;
  {
  return(x ↑ 0xff);
  };

int egetchar()  /* getchar with echo */
  {
  leftover = getchar() & 0177;
  putcrchar(leftover);
  return(leftover);
  };

int gethex()
  {
  int v;
  v = 0;
  any = 0;
  for (;;) {
    egetchar();
    if (isdigit(leftover)) {
      v = (v<<4);
      v += (leftover-'0');
      any = 1;
      continue;
      };
    leftover = lc(leftover);
    if (leftover>='a' && leftover<='f') {
      v = (v<<4);
      v += (leftover-'a'+10);
      any = 1;
      continue;
      };
    break;
    };
  return(v);
  };

InitHandlers()
  {
  AlAInt = (int) &myAlAInt;
  AlBInt = (int) &myAlBInt;
  AlCInt = (int) &myAlCInt;
  AlDInt = (int) &myAlDInt;
  SIOInt = (int) &mySIOInt;
  EncInt = (int) &myEncInt;
  SLRInt = (int) &mySLRInt;
  SLTInt = (int) &mySLTInt;
  };