Annotation of coherent/b/kernel/FWB/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: /* 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.