/* d8274.c
   Stewart, September 27, 1982  3:12 PM
   Stewart, December 20, 1982  4:57 PM, update
 */

#include "Lark.h"

extern OutByte();
extern InByte();
extern Block();

Init8274()
  {
  };

/* no blocking, for interrupt handlers to call */
nbPutChar(c)
  char c;
  {
  while (!SIOFree(0));
  SIOPutC(0, c);
  };

PutChar(c)
  char c;
  {
  PutC(0, c);
  };

PutCRChar(c)
  char c;
  {
  PutChar(c);
  if (c=='\r') PutChar('\n');
  };

PutC(ch, c)
  int ch;
  char c;
  {
  while (!SIOFree(ch)) Block();
  SIOPutC(ch, c);
  };

int GetChar()
  {
  return(GetC(0));
  };

int GetC(ch)
  int ch;
  {
  while (!AvC(ch)) Block();
  return(SIOGetC(ch) & 0177);
  };

int Chav()
  {
  return(AvC(0));
  };

int AvC(ch)
  int ch;
  {
  ch = SIOCmdP(ch);
  return(InByte(ch)&01);
  };

Baud(mbr, ch)
  int mbr, ch;
  {
  int dr, load, hold;
  if (ch == 0) {  /* use 9513 channel 0 (FOUT) */
    if (mbr == 300) { MM(0x0ac0); WR4(ch, 0x008c); };
    else WR4(ch, 0x4c);
    if (mbr==600) MM(0x0ac0);
    if (mbr==1200) MM(0x088c0);
    if (mbr==2400) MM(0x084c0);
    if (mbr==4800) MM(0x082c0);
    if (mbr==9600) MM(0x08a00);
    if (mbr==19200) MM(0x08500);
    };
  if (ch==1) {  /* use 9513 channel 4 */
    WR4(ch, 0x4c);  /* always use /16 mode */
    mbr = mbr/100;
    dr = 960/mbr;  /* 960 = 15360/16 (16 for 8274 division ratio)  */
    hold = dr/2;
    load = dr-hold;
    OutByte(TimCtl, 0xc8);  /* disarm ch 4 */
    OutByte(TimCtl, 0x04);  /* set data pointer for ch 4 */
    OutWord(TimData, 0x1b62);  /* Mode J, src F1, toggle, count up, binary */
    OutWord(TimData, load);
    OutWord(TimData, hold);
    OutByte(TimCtl, 0x48);  /* load ch 4 */
    OutByte(TimCtl, 0x28);  /* arm ch 4 */
    };
  };

static SIOFree(ch)
  int ch;
  {
  ch = SIOCmdP(ch);
  return(InByte(ch)&04);
  };

static SIOGetC(ch)
  int ch;
  {
  ch = SIODataP(ch);
  return(InByte(ch)&0177);
  };

static SIOPutC(ch, v)
  int ch;
  char v;
  {
  ch = SIODataP(ch);
  OutByte(ch, v);
  };

static SIOCmdP(ch)
  int ch;
  {
  if (ch==0) ch = sioctla;
  else ch = sioctlb;
  return(ch);
  };

static SIODataP(ch)
  int ch;
  {
  if (ch==0) ch = siodata;
  else ch = siodatb;
  return(ch);
  };

static MM(rv)
  int rv;
  {
  OutByte(TimCtl, 0x17);
  OutWord(TimData, rv);
  };

static WR4(ch, rv)
  int ch, rv;
  {
  ch = SIOCmdP(ch);
  OutByte(ch, 0x04);
  OutByte(ch, rv&0xff);
  };

static OutWord(port, val)
  int port, val;
  {
  OutByte(port, val&0xff);
  OutByte(port, (val >> 8)&0xff);
  };