Annotation of coherent/b/kernel/FWB/synth.c, revision 1.1

1.1     ! root        1: /*-----------------------------------------------------------------------------
        !             2:        Talking BIOS device driver for the AT&T PC6300.
        !             3:        Copyright (C) Karl Dahlke 1987
        !             4:        This software may be freely used and distributed
        !             5:        for any non-profit purpose.
        !             6:  *-----------------------------------------------------------------------------
        !             7:  */
        !             8: 
        !             9: /* synth.c: interface functions to the speech synthesizer */
        !            10: 
        !            11: #include "speech.h"
        !            12: 
        !            13: #ifdef MSDOS
        !            14: /* taken from Coherent ins8250.h */
        !            15: #define        DREG            0       /* Data Register               (DLAB=0) */
        !            16: #define        IER             1       /* Interrupt Enable Register   (DLAB=0) */
        !            17: #define        IIR             2       /* Interrupt Identification Register    */
        !            18: #define        FCR             2       /* FIFO Control Register                */
        !            19: #define        LCR             3       /* Line Control Register                */
        !            20: #define        MCR             4       /* Modem Control Register               */
        !            21: #define        LSR             5       /* Line Status Register                 */
        !            22: #define        MSR             6       /* Modem Status Register                */
        !            23: #define        SCR             7       /* Scratch Register                     */
        !            24: #else
        !            25: #include <sys/ins8250.h>
        !            26: #endif
        !            27: 
        !            28: #define LDLR 0 /* low divisor latch */
        !            29: #define HDLR 1 /* high divisor latch */
        !            30: 
        !            31: #ifdef MSDOS
        !            32: static int AL_ADDR[] = {0x3f8, 0x2f8, 0x3e8, 0x2e8};
        !            33: #else
        !            34: extern int AL_ADDR[];
        !            35: extern int C1BAUD, C2BAUD, C3BAUD, C4BAUD, albaud[];
        !            36: #endif
        !            37: 
        !            38: int sdoverride; /* override bad signals */
        !            39: 
        !            40: static int crticks, deadbuzz, inxmit;
        !            41: static char *xmit_ptr;
        !            42: static int i_comport; /* com port with the interrupt active */
        !            43: static short i_combase; /* AL_ADDR[i_comport-1]; */
        !            44: static struct SDCONTROL *i_sdc;
        !            45: 
        !            46: /* init the synthesizer */
        !            47: sdsynth_init(session)
        !            48: short session;
        !            49: {
        !            50: short istate;
        !            51: int synth, comport;
        !            52: int baud;
        !            53: extern int sdintr();
        !            54: 
        !            55: synth = (&sd0synth)[session];
        !            56: comport = (&sd0comport)[session];
        !            57: /* range check synth and comport */
        !            58: if(synth < 1 || synth > 1 ||
        !            59: comport < 1 || comport > 4 ||
        !            60: comport && i_comport)
        !            61: return 0;
        !            62: 
        !            63: sdcontrol[session] = i_sdc = (struct SDCONTROL *) kalloc(sizeof(struct SDCONTROL));
        !            64: if(!i_sdc) return; /* kalloc failed */
        !            65: memset(i_sdc, 0, sizeof(struct SDCONTROL));
        !            66: 
        !            67: if(comport) { /* unit is on a serial port */
        !            68: i_comport = comport;
        !            69: i_combase = AL_ADDR[comport-1];
        !            70: 
        !            71: istate = sphi();
        !            72: /* initialize the UART */
        !            73: /* no transmit interrupt until we start sending text */
        !            74: outb(i_combase+IER, 0);
        !            75: outb(i_combase+MCR, 0);
        !            76: inb(i_combase+DREG); /* clear any input */
        !            77: inb(i_combase+LSR);
        !            78: inb(i_combase+MSR);
        !            79: /* set baud rate to 9600 baud */
        !            80: baud = getbaudrate(comport);
        !            81: outb(i_combase+LCR, 0x80);
        !            82: outb(i_combase+LDLR, baud);
        !            83: outb(i_combase+HDLR, baud>>8);
        !            84: outb(i_combase+LCR, 3); /* 8 bits, no parity */
        !            85: 
        !            86: setivec((comport&1)+3, sdintr);
        !            87: 
        !            88: /* set DTR and RTS */
        !            89: /* extra bit (8[4]) is needed to generate interrupts */
        !            90: outb(i_combase+MCR, 15 - ((comport&1) << 2));
        !            91: spl(istate);
        !            92: 
        !            93: /* synthesizer specific initialization sequence here */
        !            94: return;
        !            95: } /* on a serial port */
        !            96: 
        !            97: /* this code not reached */
        !            98: return 1; /* only serial connections implemented */
        !            99: } /* sdsynth_init */
        !           100: 
        !           101: /* synthesizer appears to be dead */
        !           102: static synth_dead()
        !           103: {
        !           104: if(!deadbuzz) sdsound(7);
        !           105: deadbuzz = 1;
        !           106: i_sdc->rdflag = i_sdc->onesymb = 0;
        !           107: i_sdc->drain_lbolt = 0;
        !           108: } /* synth_dead */
        !           109: 
        !           110: /* serial port interrupt handler, runs with interrupts off */
        !           111: sdintr()
        !           112: {
        !           113: char linestat, c;
        !           114: short istate;
        !           115: 
        !           116: istate = sphi();
        !           117: inb(i_combase+IIR);
        !           118: linestat = inb(i_combase+LSR);
        !           119: if(!(linestat & 0x20)) return;
        !           120: 
        !           121: /* if no data to send then reset tx interrupt and return */
        !           122: if(!xmit_ptr) {
        !           123: outb(i_combase+IER, 0);
        !           124: inxmit = 0;
        !           125: } else {
        !           126: c = *xmit_ptr++;
        !           127: if(!c) c = '\r', xmit_ptr = 0;
        !           128: outb(i_combase+DREG, c);
        !           129: }
        !           130: 
        !           131: spl(istate);
        !           132: } /* sdintr */
        !           133: 
        !           134: /* return status of synthesizer,  ready for more or not.
        !           135:  * ideally, the unit is ready when it has spoken everything
        !           136:  * previously sent to it.  the Type & Talk has an
        !           137:  * annoying delay of about 10 seconds between ready indicated
        !           138:  * and all input spoken.  There is nothing I can do
        !           139:  * about this.  Other units, such as the echo,
        !           140:  * are out of the question, since their delay is measured
        !           141:  * in minutes.  Someday, a speech unit will indicate clearly when
        !           142:  * it has spoken all input. */
        !           143: sdready()
        !           144: {
        !           145: char mstat;
        !           146: 
        !           147: /* are we sending a string? */
        !           148: if(inxmit) return 0;
        !           149: 
        !           150: /* a real time delay, after sending return */
        !           151: if(crticks) { --crticks; return 0; }
        !           152: 
        !           153: if(!i_combase) return 1;
        !           154: 
        !           155: if(!sdoverride) {
        !           156: /* check to see if votrax is there and ready (DSR and CTS) */
        !           157: mstat = inb(i_combase+MSR);
        !           158: if(!(mstat & 0x20)) {
        !           159: synth_dead();
        !           160: return 1;
        !           161: }
        !           162: deadbuzz = 0;
        !           163: if(!(mstat & 0x10)) return 0;
        !           164: }
        !           165: 
        !           166: return 1; /* ready */
        !           167: } /* sdready */
        !           168: 
        !           169: /* send text string to the speech synthesizer.
        !           170:  * routine assumes the text is to be spoken immediately.
        !           171:  * once the text is spoken, cts will indicate ready for more. */
        !           172: sdtext(s)
        !           173: char *s;
        !           174: {
        !           175: deadbuzz = 0;
        !           176: /* is synthesizer dead? */
        !           177: if(!sdoverride && !(inb(i_combase+MSR) & 0x20)) {
        !           178: synth_dead();
        !           179: return;
        !           180: }
        !           181: 
        !           182: /* set delay, after text is transmitted, so votrax has time to disable cts */
        !           183: crticks = 1;
        !           184: xmit_ptr = s;
        !           185: inxmit = 1; /* in transmit state */
        !           186: /* enable transmit interrupt */
        !           187: outb(i_combase+IER, 2);
        !           188: } /* sdtext */
        !           189: 
        !           190: /* shut up and discard accumulated text.
        !           191:  * annoyingly, type & talk must be "ready" for text,
        !           192:  * before it will honor the shut up command (break on rs232).
        !           193:  * Be sure the unit is in the ready (cts high) state. */
        !           194: sdshutup()
        !           195: {
        !           196: char linectrl = inb(i_combase + LCR);
        !           197: outb(i_combase+LCR, linectrl|0x40);
        !           198: /* Occasionally an interrupt will come along while we are in break.
        !           199:  * This will cause the break to be a tad longer.
        !           200:  * The unbelievably picky Votrax unit may not recognize the break,
        !           201:  * and it may not shut up, or it may perceive
        !           202:  * a couple extra garbage characters.
        !           203:  * But long interrupts don't happen very often,
        !           204:  * and the short ones are potentially important,
        !           205:  * such as received characters on a serial port.
        !           206:  * So   we wait with interrupts enabled. */
        !           207: sdpause(2560);
        !           208: outb(i_combase+LCR, linectrl);
        !           209: } /* sdshutup */
        !           210: 
        !           211: /* given a port address, is it allocated to a speech unit? */
        !           212: sdport_taken(comport)
        !           213: {
        !           214: int i;
        !           215: 
        !           216: ++comport;
        !           217: 
        !           218: for(i=0; i<4; ++i)
        !           219: if((&sd0synth)[i] && comport == (&sd0comport)[i])
        !           220: return 1;
        !           221: 
        !           222: return 0;
        !           223: } /* sdport_taken */
        !           224: 
        !           225: static getbaudrate(comport)
        !           226: {
        !           227: int baud;
        !           228: #ifdef MSDOS
        !           229: baud = 12;
        !           230: #else
        !           231: switch(comport) {
        !           232: case 1: baud = albaud[C1BAUD]; break;
        !           233: case 2: baud = albaud[C2BAUD]; break;
        !           234: case 3: baud = albaud[C3BAUD]; break;
        !           235: case 4: baud = albaud[C4BAUD]; break;
        !           236: }
        !           237: #endif
        !           238: return baud;
        !           239: } /* getbaudrate */
        !           240: 

unix.superglobalmegacorp.com

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