File:  [XINU] / xinu / sys / slu7201.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:40:02 2018 UTC (8 years, 2 months ago) by root
Branches: xinu, MAIN
CVS tags: xinu-19910600, HEAD
Xinu for 68000/68010

#include <slu7201.h>

/* Package to turn the write-only control registers of each of up to MAXSLU/2
   NEC7201 SLUs into effectively read-write registers, and also initialize
   the SLU for 8 bits, no parity, 1 stop bit, 9600 baud, no interrupts.
   To be effective, all references to the control registers need to go
   through this package. */

/* space for 2 sets of saved regs, for each channel of one 7201-- */
#define MAXSLU 2

static struct {
  struct csr *csrptr;		/* which SLU this is */
  char vals[6];			/* its 6 control reg vals */
}soft_control_reg[MAXSLU] = {0};

/* initialize UART regs to do async 8 bits, no parity, 1 stop bit, no ints */
/* save control reg settings in soft_control_reg for later access */
int slu_init7201(struct csr *csrptr)
{
  int i;

  /* lookup csr or set up new spot in array-- */
  for (i=0;i<MAXSLU;i++) {
    if (soft_control_reg[i].csrptr == (struct csr *)0) {
      soft_control_reg[i].csrptr = csrptr; /* new spot */
      break;
    } else if (soft_control_reg[i].csrptr == csrptr)
      break;
  }
  if (i==MAXSLU)
    panic("Too many SLU devs for soft_control_reg table");

  csrptr->cstat = 0;		/* select reg 0 */
  csrptr->cstat = 0;		/* for sure */
  csrptr->cstat = SLURESET;
  for (i=0;i<10;i++);		/* little delay */
  soft_control_reg[i].vals[0] = 0;
  csrptr->cstat = 2;
  csrptr->cstat = SLUCREG2DEF;
  soft_control_reg[i].vals[2] = SLUCREG2DEF;
  csrptr->cstat = 4;
  csrptr->cstat = SLUCREG4DEF;
  soft_control_reg[i].vals[4] = SLUCREG4DEF;
  csrptr->cstat = 1;
  csrptr->cstat = SLUCREG1DEF;
  soft_control_reg[i].vals[1] = SLUCREG1DEF;
  csrptr->cstat = 3;
  csrptr->cstat = SLUCREG3DEF;
  soft_control_reg[i].vals[3] = SLUCREG3DEF;
  csrptr->cstat = 5;
  csrptr->cstat = SLUCREG5DEF|SLUCREG5DTR;
  soft_control_reg[i].vals[5] = SLUCREG5DEF|SLUCREG5DTR;
  csrptr->cstat = 0;		/* leave with reg 0 selected */
  *SLUSELECT9600 = 0;		/* write to magic addr for 9600 baud */
  delay7201();			/* don't use right away */
  return 0;
}

set_baudrate(int baudrate)
{
  switch (baudrate) {
  case 1200: *SLUSELECT1200 = 0;
    break;
  case 2400: *SLUSELECT2400 = 0;
    break;
  case 4800: *SLUSELECT4800 = 0;
    break;
  case 9600: *SLUSELECT9600 = 0;
    break;
  case 19200: *SLUSELECT19200 = 0;
    break;
  case 38400: *SLUSELECT38400 = 0;
    break;
  default:  return -1;
  }
  return 0;
}

delay7201()
{
  int i;

  for (i=0;i<10000;i++)
	;
}

/* call this to get current control reg contents-- */
get_control_reg7201(csrptr,reg)
struct csr *csrptr;	/* ptr to device csr */
{
  int i;

  for (i=0;i<MAXSLU;i++)
    if (soft_control_reg[i].csrptr == csrptr)
      return soft_control_reg[i].vals[reg];
  panic("Bad csrptr or uninitialized SLU");
}

/* must be called to change control reg, so that software var is maintained */
set_control_reg7201(csrptr,new_control,reg)
struct csr *csrptr;
char new_control;
{
  int i;

  for (i=0;i<MAXSLU;i++)
    if (soft_control_reg[i].csrptr == csrptr)
      break;
  if (i==MAXSLU)
    panic("Bad csrptr or uninitialized SLU");

  if (reg==0) {
    if (new_control&SLUREGMASK) /* better not set another reg! */
      panic("Inconsistent use of set_control_reg7201");
    else			/* OK, do it */
      csrptr->cstat = new_control;
  }
  else {			/* reg>0--select reg, do it, reselect reg 0 */
    csrptr->cstat = reg;	/* select reg */
    csrptr->cstat = new_control;
    csrptr->cstat = 0;		/*  back to reg 0 */
  }
  delay7201();			/* let 7201 have time to process cmd */
  soft_control_reg[i].vals[reg] = new_control;
  return 0;
}
/* used by slutenable macro--reenable transmit ints if necessary,
   start output with null char */
slu_tstart7201(csrptr)
struct csr *csrptr;
{
  short savesr,creg1;
  int i;

  for (i=0;i<MAXSLU;i++)
    if (soft_control_reg[i].csrptr == csrptr)
      break;
  if (i==MAXSLU)
    panic("Bad csrptr or uninitialized SLU");

  _disable(&savesr);		/* make sure test,set of int bit is atomic  */
  if ((creg1 = soft_control_reg[i].vals[1])&SLUTRANSIE) {
    _restore(&savesr);
    return;			/* already going */
  }
  while ((csrptr->cstat&SLUTRANSREADY)==0) ; /* make sure transmitter idle */
  set_control_reg7201(csrptr,creg1|SLUTRANSIE,1); /* set int. bit */
  csrptr->cbuf = 0;		/* start output */
  _restore(&savesr);
}


  

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.