Annotation of coherent/b/kernel/FWB2/synth.c, revision 1.1.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: /* replace ? in error message with session number, then print */
                     47: static fix_ques(s, n)
                     48: char *s;
                     49: {
                     50: extern char *strchr();
                     51: s = strchr(s,'?');
                     52: if(s) *s = n+'0';
                     53: printf(s);
                     54: } /* fix_ques */
                     55: 
                     56: /* init the synthesizer */
                     57: sdsynth_init(session)
                     58: short session;
                     59: {
                     60: short istate;
                     61: int synth, comport;
                     62: int baud;
                     63: static char emsg1[] = "ERROR: patchable variable sd?synth is out of range";
                     64: static char emsg2[] = "ERROR: patchable variable sd?comport is out of range";
                     65: static char emsg3[] = "ERROR: synthesizer must run on a serial port, please patch sd?comport\n";
                     66: static char emsg4[] = "ERROR: synthesizer cannot run on a serial port, please patch sd?comport to 0\n";
                     67: static char emsg5[] = "ERROR: only one speech session can be activated, and it must run from the console\n";
                     68: static char emsg6[] = "ERROR: cannot allocate structure for speech session ?\n";
                     69: static char emsg7[] = "ERROR: speech session cannot use com?, no UART present\n";
                     70: /* for each synthesizer, is it external or internal? */
                     71: static char inout[] = {0, 2};
                     72: extern int sdintr();
                     73: 
                     74: synth = (&sd0synth)[session];
                     75: comport = (&sd0comport)[session];
                     76: 
                     77: if(synth < 0 || synth > 1) {
                     78: fix_ques(emsg1, session);
                     79: return;
                     80: }
                     81: 
                     82: if(!synth) return;
                     83: 
                     84: if(comport < 0 || comport > 4) {
                     85: fix_ques(emsg2, session);
                     86: return;
                     87: }
                     88: 
                     89: if(comport && !(inout[synth]&2)) {
                     90: fix_ques(emsg3, session);
                     91: return;
                     92: }
                     93: 
                     94: if(!comport && !(inout[synth]&1)) {
                     95: fix_ques(emsg4, session);
                     96: return;
                     97: }
                     98: 
                     99: if(session || i_comport) {
                    100: fix_ques(emsg5, session);
                    101: return;
                    102: }
                    103: 
                    104: sdcontrol[session] = i_sdc = (struct SDCONTROL *) kalloc(sizeof(struct SDCONTROL));
                    105: if(!i_sdc) {; /* kalloc failed */
                    106: fix_ques(emsg6, session);
                    107: return;
                    108: }
                    109: memset(i_sdc, 0, sizeof(struct SDCONTROL));
                    110: 
                    111: if(comport) { /* unit is on a serial port */
                    112: i_comport = comport;
                    113: i_combase = AL_ADDR[comport-1];
                    114: 
                    115: /* set vector early, to handle any spurious interrupts */
                    116: setivec((comport&1)+3, sdintr);
                    117: 
                    118: #ifndef MSDOS
                    119: if(uart_sense(i_combase) == US_NONE) {
                    120: fix_ques(emsg7, comport);
                    121: fail:
                    122: kfree(i_sdc);
                    123: sdcontrol[session] = 0;
                    124: clrivec((comport&1)+3);
                    125: return;
                    126: }
                    127: printf(" monopolized by console speech session\n");
                    128: #endif
                    129: 
                    130: istate = sphi();
                    131: /* initialize the UART */
                    132: /* no transmit interrupt until we start sending text */
                    133: outb(i_combase+IER, 0);
                    134: outb(i_combase+MCR, 0);
                    135: inb(i_combase+DREG); /* clear any input */
                    136: inb(i_combase+LSR);
                    137: inb(i_combase+MSR);
                    138: /* set baud rate to 9600 baud */
                    139: baud = getbaudrate(comport);
                    140: outb(i_combase+LCR, 0x80);
                    141: outb(i_combase+LDLR, baud);
                    142: outb(i_combase+HDLR, baud>>8);
                    143: outb(i_combase+LCR, 3); /* 8 bits, no parity */
                    144: 
                    145: /* set DTR and RTS */
                    146: /* extra bit (8[4]) is needed to generate interrupts */
                    147: outb(i_combase+MCR, 15 - ((comport&1) << 2));
                    148: spl(istate);
                    149: 
                    150: /* synthesizer specific initialization sequence here */
                    151: return;
                    152: } /* on a serial port */
                    153: 
                    154: /* this code not reached */
                    155: return; /* only serial connections implemented */
                    156: } /* sdsynth_init */
                    157: 
                    158: /* synthesizer appears to be dead */
                    159: static synth_dead()
                    160: {
                    161: if(!deadbuzz) sdsound(7);
                    162: deadbuzz = 1;
                    163: i_sdc->rdflag = i_sdc->onesymb = 0;
                    164: i_sdc->drain_lbolt = 0;
                    165: } /* synth_dead */
                    166: 
                    167: /* serial port interrupt handler, runs with interrupts off */
                    168: sdintr()
                    169: {
                    170: char linestat, c;
                    171: short istate;
                    172: 
                    173: istate = sphi();
                    174: inb(i_combase+IIR);
                    175: linestat = inb(i_combase+LSR);
                    176: if(linestat & 0x20) {
                    177: 
                    178: if(inxmit) {
                    179: /* if no data to send then reset tx interrupt and return */
                    180: if(!xmit_ptr) {
                    181: outb(i_combase+IER, 0);
                    182: inxmit = 0;
                    183: } else {
                    184: c = *xmit_ptr++;
                    185: if(!c) c = '\r', xmit_ptr = 0;
                    186: outb(i_combase+DREG, c);
                    187: }
                    188: }
                    189: }
                    190: 
                    191: spl(istate);
                    192: } /* sdintr */
                    193: 
                    194: /* return status of synthesizer,  ready for more or not.
                    195:  * ideally, the unit is ready when it has spoken everything
                    196:  * previously sent to it.  the Type & Talk has an
                    197:  * annoying delay of about 10 seconds between ready indicated
                    198:  * and all input spoken.  There is nothing I can do
                    199:  * about this.  Other units, such as the echo,
                    200:  * are out of the question, since their delay is measured
                    201:  * in minutes.  Someday, a speech unit will indicate clearly when
                    202:  * it has spoken all input. */
                    203: sdready(session)
                    204: /* only works for one session, i_sdc, ignore passed parameter */
                    205: int session;
                    206: {
                    207: char mstat;
                    208: 
                    209: /* are we sending a string? */
                    210: if(inxmit) return 0;
                    211: 
                    212: /* a real time delay, after sending return */
                    213: if(crticks) { --crticks; return 0; }
                    214: 
                    215: if(!i_combase) return 1;
                    216: 
                    217: if(!sdoverride) {
                    218: /* check to see if votrax is there and ready (DSR and CTS) */
                    219: mstat = inb(i_combase+MSR);
                    220: if(!(mstat & 0x20)) {
                    221: synth_dead();
                    222: return 1;
                    223: }
                    224: deadbuzz = 0;
                    225: if(!(mstat & 0x10)) return 0;
                    226: }
                    227: 
                    228: return 1; /* ready */
                    229: } /* sdready */
                    230: 
                    231: /* send text string to the speech synthesizer.
                    232:  * routine assumes the text is to be spoken immediately.
                    233:  * once the text is spoken, cts will indicate ready for more. */
                    234: sdtext(s)
                    235: char *s;
                    236: {
                    237: deadbuzz = 0;
                    238: /* is synthesizer dead? */
                    239: if(!sdoverride && !(inb(i_combase+MSR) & 0x20)) {
                    240: synth_dead();
                    241: return;
                    242: }
                    243: 
                    244: /* set delay, after text is transmitted, so votrax has time to disable cts */
                    245: crticks = 1;
                    246: xmit_ptr = s;
                    247: inxmit = 1; /* in transmit state */
                    248: /* enable transmit interrupt */
                    249: outb(i_combase+IER, 2);
                    250: } /* sdtext */
                    251: 
                    252: /* shut up and discard accumulated text.
                    253:  * annoyingly, type & talk must be "ready" for text,
                    254:  * before it will honor the shut up command (break on rs232).
                    255:  * Be sure the unit is in the ready (cts high) state. */
                    256: sdshutup()
                    257: {
                    258: char linectrl = inb(i_combase + LCR);
                    259: outb(i_combase+LCR, linectrl|0x40);
                    260: /* Occasionally an interrupt will come along while we are in break.
                    261:  * This will cause the break to be a tad longer.
                    262:  * The unbelievably picky Votrax unit may not recognize the break,
                    263:  * and it may not shut up, or it may perceive
                    264:  * a couple extra garbage characters.
                    265:  * But long interrupts don't happen very often,
                    266:  * and the short ones are potentially important,
                    267:  * such as received characters on a serial port.
                    268:  * So   we wait with interrupts enabled. */
                    269: sdpause(2560);
                    270: outb(i_combase+LCR, linectrl);
                    271: } /* sdshutup */
                    272: 
                    273: /* given a port address, is it allocated to a speech unit? */
                    274: sdport_taken(comport)
                    275: {
                    276: int i;
                    277: 
                    278: ++comport;
                    279: 
                    280: for(i=0; i<4; ++i)
                    281: if((&sd0synth)[i] && comport == (&sd0comport)[i])
                    282: return 1;
                    283: 
                    284: return 0;
                    285: } /* sdport_taken */
                    286: 
                    287: static getbaudrate(comport)
                    288: {
                    289: int baud;
                    290: #ifdef MSDOS
                    291: baud = 12;
                    292: #else
                    293: switch(comport) {
                    294: case 1: baud = albaud[C1BAUD]; break;
                    295: case 2: baud = albaud[C2BAUD]; break;
                    296: case 3: baud = albaud[C3BAUD]; break;
                    297: case 4: baud = albaud[C4BAUD]; break;
                    298: }
                    299: #endif
                    300: return baud;
                    301: } /* getbaudrate */
                    302: 

unix.superglobalmegacorp.com

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