/* di8274.c interrupt driver for 8274 Stewart, November 8, 1982 2:56 PM November 8, 1982 5:09 PM osstatics, add nbPutChar() February 23, 1983 10:32 AM remove wdc February 23, 1983 12:53 PM remove osstatics February 23, 1983 2:56 PM new EnableInt, FlushInput, CallSwat -> CallDebug, flush Set8274 February 26, 1983 3:33 PM EOI fixes */ #include "ec.h" #include "Lark.h" #include "env.h" #include "RingBuffer.h" /* context */ extern Block(); /* interrupts */ extern EnableInt(); /* runtime */ extern CallDebugger(); /* ringbuffer */ extern InitRingBuffer(); extern WriteRingBuffer(); extern RingBufferEmpty(); extern ReadRingBuffer(); /* machine code */ extern OutByte(); extern InByte(); extern /* FORWARD */ mySIOInt(); static struct CBuf rb[2]; static struct CBuf tb[2]; static int busy[2]; Init8274() { FlushInput(0); FlushInput(1); InitRingBuffer(&tb[0], tb[0].abuf, CBS-2); InitRingBuffer(&tb[1], tb[1].abuf, CBS-2); busy[0] = busy[1] = false; Baud(1200, 0); Baud(1200, 1); EnableInt(&mySIOInt, SIOTyp); }; FlushInput(ch) int ch; { if (ch) InitRingBuffer(&rb[1], rb[1].abuf, CBS-2); else InitRingBuffer(&rb[0], rb[0].abuf, CBS-2); }; nbPutChar(c) char c; { struct CBuf *p; p = &tb[0]; while (!WriteRingBuffer(p, c)); if (!busy[0] && !RingBufferEmpty(p)) { busy[0] = 1; SIOPutC(0, ReadRingBuffer(p)); }; }; 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; { struct CBuf *p; p = &tb[ch]; while (!WriteRingBuffer(p, c)) Block(); if (!busy[ch] && !RingBufferEmpty(p)) { busy[ch] = 1; SIOPutC(ch, ReadRingBuffer(p)); }; }; int GetChar() { return(GetC(0)); }; int GetC(ch) int ch; { struct CBuf *p; p = &rb[ch]; while (RingBufferEmpty(p)) Block(); return(ReadRingBuffer(p) & 0177); }; int Chav() { return(AvC(0)); }; int AvC(ch) int ch; { return(!RingBufferEmpty(&rb[ch])); }; 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 int iretCode; static mySIOInt() { int type; /* read RR2 of ch. B to get modified vector */ type = RR2(1) & 07; switch (type) { case 0: txe(1); break; case 1: CallD(ecInt+2); break; case 2: rxa(1); break; case 3: sprx(1); break; case 4: txe(0); break; case 5: CallD(ecInt+3); break; case 6: rxa(0); break; case 7: sprx(0); break; default: CallD(ecInt+1); }; if (iretCode) WR0(0, 0x38); /* eoi */ return(iretCode); }; CallD(n) int n; { WR0(0, 0x38); /* eoi */ DoEOI(); iretCode = false; CallDebugger(n); }; static rxa(ch) int ch; { char c; iretCode = true; c = SIOGetC(ch); if (c == 0) CallD(0); else WriteRingBuffer(&rb[ch], c); }; static txe(ch) int ch; { struct CBuf *p; iretCode = true; p = &tb[ch]; if (RingBufferEmpty(p)) { WR0(ch, 0x28); busy[ch] = 0; }; else SIOPutC(ch, ReadRingBuffer(p)); }; static sprx(ch) int ch; { iretCode = true; WR0(ch, 0xf0); /* forget it */ }; static WR0(ch, rv) int ch, rv; { ch = SIOCmdP(ch); OutByte(ch, rv&0xff); }; static int RR2(ch) int ch; { ch = SIOCmdP(ch); OutByte(ch, 2); return(InByte(ch) & 0xff); }; 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); };