Annotation of coherent/b/kernel/FWB2/noises.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: /* noises.c: generate sounds */
                     10: 
                     11: #ifndef MSDOS
                     12: #include <sys/io.h>
                     13: #endif
                     14: #include "speech.h"
                     15: 
                     16: /* intervals, measured in ticks of the timer */
                     17: #define TICKS_CYCLE 11932
                     18: #define TICKS_CLICK 1000
                     19: #define TICKS_CHARWAIT 7200
                     20: #define TICKS_TOPCR 560
                     21: #define TICKS_BOTCR 64
                     22: #define TICKS_INCCR 5
                     23: 
                     24: #define DRAINTICKS 770 /* how long till the squawker's internal buffer is drained */
                     25: 
                     26: #define SF_LEN 32 /* length of sound fifo */
                     27: 
                     28: long lbolt;
                     29: extern int mmticks;
                     30: 
                     31: /* sound control variables, console only */
                     32: int sdnoises = 1, sdtones = 0;
                     33: 
                     34: static short sf_fifo[SF_LEN];
                     35: static int sf_head, sf_tail;
                     36: static long wait_lbolt;
                     37: 
                     38: static freqset(freq)
                     39: int freq;
                     40: {
                     41: short istate;
                     42: istate = sphi();
                     43: if(freq < 0) /* turn off tone */
                     44: outb(0x61, inb(0x61) & ~1);
                     45: else {
                     46: outb(0x43, 0xb6);
                     47: outb(0x42, freq);
                     48: outb(0x42, (freq>>8));
                     49: outb(0x61, inb(0x61) | 3);
                     50: }
                     51: spl(istate);
                     52: } /* freqset */
                     53: 
                     54: static putfifo(p)
                     55: short *p;
                     56: {
                     57: short istate;
                     58: int i;
                     59: 
                     60: istate = sphi();
                     61: i = sf_head;
                     62: while(*p) {
                     63: sf_fifo[i++] = *p++;
                     64: if(i == SF_LEN) i = 0;
                     65: if(i == sf_tail) goto done;
                     66: }
                     67: sf_head = i;
                     68: 
                     69: done: spl(istate);
                     70: } /* putfifo */
                     71: 
                     72: chkfifo()
                     73: {
                     74: int i;
                     75: short freq;
                     76: long l;
                     77: 
                     78: if(wait_lbolt) {
                     79: l = lbolt - wait_lbolt;
                     80: if(l >= 0 || l <= -1000) {
                     81: freqset(-1);
                     82: wait_lbolt = 0;
                     83: }
                     84: }
                     85: 
                     86: if(!wait_lbolt) {
                     87: if((i = sf_tail) != sf_head) {
                     88: freq = sf_fifo[i++];
                     89: if(i == SF_LEN) i = 0;
                     90: l = sf_fifo[i++];
                     91: if(i == SF_LEN) i = 0;
                     92: sf_tail = i;
                     93: freqset(freq);
                     94: wait_lbolt = lbolt + l;
                     95: }
                     96: }
                     97: 
                     98: #ifndef MSDOS
                     99: if(wait_lbolt && mmticks == 10) mmticks = 1; /* higher resolution */
                    100: #endif
                    101: } /* chkfifo */
                    102: 
                    103: /* generate a sound based on the passed parameter */
                    104: /* should only be called when the session runs on the console */
                    105: sdsound(sound)
                    106: {
                    107: short *snd_array;
                    108: static short startsnd[] = {2000,10,1500,10,1333,10,1123,10,0,0};
                    109: static short bellsnd[] = {662,5,0,0};
                    110: static short boundsnd[] = {376,3,316,3,0,0};
                    111: static short offsnd[] = {4800,3,0,0};
                    112: static short onsnd[] = {2000,10,0,0};
                    113: static short buzzsnd[] = {8000,20,0,0};
                    114: static short *soundlist[] = {
                    115: 0, 0, 0, bellsnd, boundsnd, offsnd, onsnd, buzzsnd, startsnd};
                    116: 
                    117: if(!sdnoises) return;
                    118: 
                    119: snd_array = soundlist[sound];
                    120: if(snd_array)
                    121: putfifo(snd_array);
                    122: if(sound == 2) crsnd();
                    123: if(sound == 1) spk_click();
                    124: } /* sdsound */
                    125: 
                    126: /* under Coherent, we return an integer that indicates whether
                    127:  * the mmtime() function should take a real time break before processing
                    128:  * this or subsequent characters.
                    129:  * Sometimes the time to wait before creating the click of the next
                    130:  * character extends beyond the next system clock interrupt.
                    131:  * In this case, there is no point in hogging the CPU.
                    132:  * Return 1 to indicate that this character should be held,
                    133:  * and acted upon once the mmtime() function is reinvoked
                    134:  * at the next system clock interrupt, unless of course there
                    135:  * is something else ready to run, such as my wife's word processor
                    136:  * or a cron job.
                    137:  * A return of 0 means we waited the proper amount of time and made the
                    138:  * corresponding noise, and we are ready to receive the next character.
                    139:  * If we are running musical output, the tone must persist for approx
                    140:  * a tenth of a second. Return 2 to indicate this. */
                    141: int sdcharsnd(c)
                    142: char c;
                    143: {
                    144: /* lr_notes[i] = 1193181/(1000*1.02^(i+1)) */
                    145: static short lr_notes[] = {
                    146: 1168,1146,1124,1102,1080,1060,1038,1018,1000,980,960,942,924,906,888,872,
                    147: 854,838,822,806,790,774,760,744,730,716,702,688,674,662,648,636,
                    148: 624,612,600,588,576,566,554,544,532,522,512,502,492,482,474,464,
                    149: 454,446,438,428,420,412,404,396,388,380,374,366,358,352,344,338};
                    150: 
                    151: /* make sound accompanying this character */
                    152: if(sdtones) {
                    153: #ifdef MSDOS
                    154: while(wait_lbolt || sf_head != sf_tail)  ;
                    155: #endif
                    156: 
                    157: if(c == 13) sdsound(2);
                    158: if(c >= 96) c -= 32;
                    159: freqset(-1);
                    160: if(c > ' ') freqset(lr_notes[c-' ']);
                    161: wait_lbolt = lbolt + 5;
                    162: return 8;
                    163: } /* sdtones */
                    164: 
                    165: if(sdnoises) {
                    166: switch(c) {
                    167: case 7: sdsound(3); break;
                    168: case 13: sdsound(2); break;
                    169: default:
                    170: if(c > ' ')
                    171: sdsound(1);
                    172: #ifdef MSDOS
                    173: else
                    174: sdpause(TICKS_CLICK);
                    175: #endif
                    176: break;
                    177: }
                    178: #ifdef MSDOS
                    179: sdpause(TICKS_CHARWAIT - TICKS_CLICK);
                    180: #endif
                    181: return 4;
                    182: } /* noises on */
                    183: 
                    184: return 0;
                    185: } /* sdcharsnd */
                    186: 
                    187: /* sound for turning a mode on or off, from within a deferred function */
                    188: sdonoff(onoff)
                    189: {
                    190: if(!sdsession)
                    191: sdsound(5+onoff);
                    192: } /* sdonoff */
                    193: 
                    194: draincheck()
                    195: {
                    196: long l;
                    197: 
                    198: if(sdc->drain_lbolt) {
                    199: l = lbolt - sdc->drain_lbolt;
                    200: if(l < 0 && l > -1000)
                    201: return 1; /* still waiting */
                    202: sdc->drain_lbolt = 0;
                    203: }
                    204: 
                    205: return 0;
                    206: } /* draincheck */
                    207: 
                    208: drainset(o)
                    209: struct SDCONTROL *o;
                    210: {
                    211: o->drain_lbolt = lbolt + DRAINTICKS;
                    212: } /* drainset */
                    213: 
                    214: /* togle the inbuilt speaker */
                    215: static spk_toggle()
                    216: {
                    217: short istate = sphi();
                    218: char c;
                    219: c = inb(0x61);
                    220: /* cannot interrupt a tone with a click */
                    221: if(!(c&1))
                    222: outb(0x61, c^2);
                    223: spl(istate);
                    224: } /* spk_toggle */
                    225: 
                    226: /* pause this many clock ticks */
                    227: sdpause(nticks)
                    228: {
                    229: int t0val = read_t0();
                    230: int nextval;
                    231: do {
                    232: nextval = read_t0();
                    233: t0val -= nextval;
                    234: #ifndef MSDOS
                    235: if(t0val < 0) t0val += TICKS_CYCLE;
                    236: #endif
                    237: nticks -= t0val;
                    238: t0val = nextval;
                    239: } while(nticks > 0);
                    240: } /* sdpause */
                    241: 
                    242: /* the sound of a character click */
                    243: static spk_click()
                    244: {
                    245: spk_toggle();
                    246: sdpause(TICKS_CLICK);
                    247: spk_toggle();
                    248: } /* spk_click */
                    249: 
                    250: crsnd()
                    251: {
                    252: int i, nticks, nextval;
                    253: int t0val = read_t0();
                    254: 
                    255: for(i=TICKS_TOPCR; i>TICKS_BOTCR; i-=TICKS_INCCR) {
                    256: spk_toggle();
                    257: nticks = i;
                    258: do {
                    259: nextval = read_t0();
                    260: t0val -= nextval;
                    261: #ifndef MSDOS
                    262: if(t0val < 0) t0val += TICKS_CYCLE;
                    263: #endif
                    264: nticks -= t0val;
                    265: t0val = nextval;
                    266: } while(nticks > 0);
                    267: }
                    268: } /* crsnd */
                    269: 
                    270: #ifndef MSDOS
                    271: /* return nonzero if we need to take a real time break */
                    272: mmgo1(c)
                    273: int c;
                    274: {
                    275: int rc; /* return value */
                    276:        IO iob;
                    277: 
                    278: /* set up for mmgo() */
                    279:                iob.io_seg  = IOSYS;
                    280:                iob.io_ioc  = 1;
                    281:                iob.io.vbase = &c;
                    282:                iob.io_flag = 0;
                    283: 
                    284: mmticks = 1;
                    285: 
                    286: rc = sdoutchar(0, c);
                    287: 
                    288: if(rc & 2) {
                    289: int c1 = c;
                    290: c = '\33';
                    291: mmgo(&iob);
                    292: c = c1;
                    293: }
                    294: 
                    295: if(rc & 1) mmgo(&iob);
                    296: 
                    297: if(rc & 8) {
                    298: mmticks = 7;
                    299: return 1;
                    300: }
                    301: 
                    302: if(rc & 4) {
                    303: mmticks = 1;
                    304: return 2;
                    305: }
                    306: 
                    307: return 0;
                    308: } /* mmgo1 */
                    309: 
                    310: #endif

unix.superglobalmegacorp.com

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