| plan 9 kernel history: overview | file list | diff list |
1995/0119/port/devaudio.c (diff list | history)
| 1995/0119/sys/src/9/port/devaudio.c:11,18 – 1995/0214/sys/src/9/port/devaudio.c:11,16 (short | long) | ||
| 1995/0119 | #include "io.h" #include "audio.h" | |
| 1995/0119/sys/src/9/port/devaudio.c:26,32 – 1995/0214/sys/src/9/port/devaudio.c:24,31 | ||
| 1995/0119 | Fmono = 1, | |
| 1995/0214 | Aclosed = 0, Aread, | |
| 1995/0119 | Awrite, Speed = 44100, | |
| 1995/0119/sys/src/9/port/devaudio.c:67,78 – 1995/0214/sys/src/9/port/devaudio.c:66,78 | ||
| 1995/0119 | }; static struct { | |
| 1995/0214 | QLock; | |
| 1995/0119 | Rendez vous; int bufinit; /* boolean if buffers allocated */ int curcount; /* how much data in current buffer */ int active; /* boolean dma running */ int intr; /* boolean an interrupt has happened */ | |
| 1995/0214 | int amode; /* Aclosed/Aread/Awrite for /audio */ | |
| 1995/0119 | Level left; /* all of left volumes */ Level right; /* all of right volumes */ int mic; /* mono level */ | |
| 1995/0119/sys/src/9/port/devaudio.c:121,129 – 1995/0214/sys/src/9/port/devaudio.c:121,144 | ||
| 1995/0119 | 0 }; | |
| 1995/0214 | static struct { Lock; int reset; /* io ports to the sound blaster */ int read; int write; int wstatus; int rstatus; int mixaddr; int mixdata; int clri8; int clri16; int clri401; } blaster; | |
| 1995/0119 | static void swab(uchar*); | |
| 1995/0214 | static char Emajor[] = "SoundBlaster version too old"; | |
| 1995/0119 | static char Emode[] = "illegal open mode"; static char Evolume[] = "illegal volume specifier"; | |
| 1995/0119/sys/src/9/port/devaudio.c:133,141 – 1995/0214/sys/src/9/port/devaudio.c:148,156 | ||
| 1995/0119 | int i, s; for(i=1<<16; i!=0; i--) { | |
| 1995/0214 | s = inb(blaster.wstatus); | |
| 1995/0119 | if((s & 0x80) == 0) { | |
| 1995/0214 | outb(blaster.write, val); | |
| 1995/0119 | return 0; } } | |
| 1995/0119/sys/src/9/port/devaudio.c:149,157 – 1995/0214/sys/src/9/port/devaudio.c:164,172 | ||
| 1995/0119 | int i, s; for(i=1<<16; i!=0; i--) { | |
| 1995/0214 | s = inb(blaster.rstatus); | |
| 1995/0119 | if((s & 0x80) != 0) { | |
| 1995/0214 | return inb(blaster.read); | |
| 1995/0119 | } } /* print("SB16 sbread did not respond\n"); /**/ | |
| 1995/0119/sys/src/9/port/devaudio.c:162,169 – 1995/0214/sys/src/9/port/devaudio.c:177,184 | ||
| 1995/0119 | mxcmd(int addr, int val) { | |
| 1995/0214 | outb(blaster.mixaddr, addr); outb(blaster.mixdata, val); | |
| 1995/0119 | return 1; } | |
| 1995/0119/sys/src/9/port/devaudio.c:172,179 – 1995/0214/sys/src/9/port/devaudio.c:187,194 | ||
| 1995/0119 | { int s; | |
| 1995/0214 | outb(blaster.mixaddr, addr); s = inb(blaster.mixdata); | |
| 1995/0119 | return s; } | |
| 1995/0119/sys/src/9/port/devaudio.c:214,222 – 1995/0214/sys/src/9/port/devaudio.c:229,235 | ||
| 1995/0119 | static void mxvolume(void) { | |
| 1995/0214 | ilock(&blaster); | |
| 1995/0119 | mxcmds(0x30, audio.left.master); mxcmds(0x31, audio.right.master); | |
| 1995/0119/sys/src/9/port/devaudio.c:249,255 – 1995/0214/sys/src/9/port/devaudio.c:262,268 | ||
| 1995/0119 | mxcmd(0x3c, audio.oswitch); mxcmd(0x3d, audio.left.iswitch); mxcmd(0x3e, audio.right.iswitch); | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } static Buf* | |
| 1995/0119/sys/src/9/port/devaudio.c:287,293 – 1995/0214/sys/src/9/port/devaudio.c:300,305 | ||
| 1995/0119 | contindma(void) { Buf *b; | |
| 1995/0119/sys/src/9/port/devaudio.c:306,329 – 1995/0214/sys/src/9/port/devaudio.c:318,328 | ||
| 1995/0119 | if(b == 0) goto shutdown; | |
| 1995/0214 | dmasetup(Dma, b->virt, Bufsize, audio.amode == Aread); | |
| 1995/0119 | return; shutdown: | |
| 1995/0214 | dmaend(Dma); | |
| 1995/0119 | sbcmd(0xd9); /* exit at end of count */ sbcmd(0xd5); /* pause */ audio.curcount = 0; | |
| 1995/0119/sys/src/9/port/devaudio.c:339,352 – 1995/0214/sys/src/9/port/devaudio.c:338,349 | ||
| 1995/0119 | { ulong count; | |
| 1995/0214 | ilock(&blaster); dmaend(Dma); if(audio.amode == Aread) | |
| 1995/0119 | sbcmd(0x42); /* input sampling rate */ | |
| 1995/0214 | else | |
| 1995/0119 | sbcmd(0x41); /* output sampling rate */ | |
| 1995/0119/sys/src/9/port/devaudio.c:361,366 – 1995/0214/sys/src/9/port/devaudio.c:358,364 | ||
| 1995/0119 | audio.active = 1; contindma(); | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } /* | |
| 1995/0119/sys/src/9/port/devaudio.c:370,381 – 1995/0214/sys/src/9/port/devaudio.c:368,375 | ||
| 1995/0119 | static void pokeaudio(void) { | |
| 1995/0119/sys/src/9/port/devaudio.c:387,402 – 1995/0214/sys/src/9/port/devaudio.c:381,398 | ||
| 1995/0119 | if(stat) { dummy = 0; if(stat & 2) { | |
| 1995/0214 | ilock(&blaster); dummy = inb(blaster.clri16); | |
| 1995/0119 | contindma(); | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | audio.intr = 1; wakeup(&audio.vous); } if(stat & 1) { | |
| 1995/0214 | dummy = inb(blaster.clri8); | |
| 1995/0119 | } if(stat & 4) { | |
| 1995/0214 | dummy = inb(blaster.clri401); | |
| 1995/0119 | } USED(dummy); } | |
| 1995/0119/sys/src/9/port/devaudio.c:403,408 – 1995/0214/sys/src/9/port/devaudio.c:399,412 | ||
| 1995/0119 | } void | |
| 1995/0214 | pcaudiosbintr(Ureg *ureg, void *rock) { USED(ureg, rock); /* print("sb16 audio interrupt\n"); /**/ audiosbintr(); } void | |
| 1995/0119 | audiodmaintr(void) { /* print("sb16 dma interrupt\n"); /**/ | |
| 1995/0119/sys/src/9/port/devaudio.c:427,433 – 1995/0214/sys/src/9/port/devaudio.c:431,437 | ||
| 1995/0119 | pokeaudio(); tsleep(&audio.vous, anybuf, 0, 10*1000); if(audio.intr == 0) { | |
| 1995/0214 | print("audio timeout\n"); /**/ | |
| 1995/0119 | audio.active = 0; pokeaudio(); } | |
| 1995/0119/sys/src/9/port/devaudio.c:452,457 – 1995/0214/sys/src/9/port/devaudio.c:456,462 | ||
| 1995/0119 | { int i; | |
| 1995/0214 | ilock(&blaster); | |
| 1995/0119 | audio.empty.first = 0; audio.empty.last = 0; audio.full.first = 0; | |
| 1995/0119/sys/src/9/port/devaudio.c:460,465 – 1995/0214/sys/src/9/port/devaudio.c:465,471 | ||
| 1995/0119 | audio.filling = 0; for(i=0; i<Nbuf; i++) putbuf(&audio.empty, &audio.buf[i]); | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } void | |
| 1995/0119/sys/src/9/port/devaudio.c:481,495 – 1995/0214/sys/src/9/port/devaudio.c:487,542 | ||
| 1995/0119 | void audioinit(void) { | |
| 1995/0214 | ISAConf sbconf; | |
| 1995/0119 | int i; | |
| 1995/0214 | sbconf.port = 0x220; sbconf.irq = 7; if(isaconfig("audio", 0, &sbconf) == 0) return; if(strcmp(sbconf.type, "sb16") != 0) return; switch(sbconf.port){ case 0x220: case 0x240: case 0x260: case 0x280: break; default: print("bad sb16 port 0x%x\n", sbconf.port); return; } switch(sbconf.irq){ case 2: case 5: case 7: case 10: break; default: print("bad sb16 irq %d\n", sbconf.irq); return; } blaster.reset = sbconf.port + 0x6; blaster.read = sbconf.port + 0xa; blaster.write = sbconf.port + 0xc; blaster.wstatus = sbconf.port + 0xc; blaster.rstatus = sbconf.port + 0xe; blaster.mixaddr = sbconf.port + 0x4; blaster.mixdata = sbconf.port + 0x5; blaster.clri8 = sbconf.port + 0xe; blaster.clri16 = sbconf.port + 0xf; blaster.clri401 = sbconf.port + 0x100; | |
| 1995/0119 | seteisadma(Dma, audiodmaintr); | |
| 1995/0214 | setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0); | |
| 1995/0119 | ||
| 1995/0214 | audio.amode = Aclosed; | |
| 1995/0119 | resetlevel(); | |
| 1995/0214 | outb(blaster.reset, 1); | |
| 1995/0119 | delay(1); /* >3 υs */ | |
| 1995/0214 | outb(blaster.reset, 0); | |
| 1995/0119 | delay(1); i = sbread(); | |
| 1995/0119/sys/src/9/port/devaudio.c:516,525 – 1995/0214/sys/src/9/port/devaudio.c:563,572 | ||
| 1995/0119 | * set up irq/dma chans */ mxcmd(0x80, /* irq */ | |
| 1995/0214 | (sbconf.irq==2)? 1: (sbconf.irq==5)? 2: (sbconf.irq==7)? 4: (sbconf.irq==10)? 8: | |
| 1995/0119 | 0); mxcmd(0x81, 1<<Dma); /* dma */ } | |
| 1995/0119/sys/src/9/port/devaudio.c:551,556 – 1995/0214/sys/src/9/port/devaudio.c:598,604 | ||
| 1995/0119 | Chan* audioopen(Chan *c, int omode) { | |
| 1995/0214 | int amode; | |
| 1995/0119 | if(audio.major != 4) error(Emajor); | |
| 1995/0119/sys/src/9/port/devaudio.c:565,581 – 1995/0214/sys/src/9/port/devaudio.c:613,634 | ||
| 1995/0119 | break; case Qaudio: | |
| 1995/0214 | amode = Awrite; if((omode&7) == OREAD) amode = Aread; qlock(&audio); if(audio.amode != Aclosed){ qunlock(&audio); error(Einuse); } | |
| 1995/0119 | if(audio.bufinit == 0) { audio.bufinit = 1; sbbufinit(); } | |
| 1995/0214 | audio.amode = amode; | |
| 1995/0119 | setempty(); audio.curcount = 0; | |
| 1995/0214 | qunlock(&audio); | |
| 1995/0119 | break; } c = devopen(c, omode, audiodir, NPORT, devgen); | |
| 1995/0119/sys/src/9/port/devaudio.c:612,620 – 1995/0214/sys/src/9/port/devaudio.c:665,681 | ||
| 1995/0119 | case Qaudio: if(c->flag & COPEN) { | |
| 1995/0214 | qlock(&audio); audio.amode = Aclosed; if(waserror()){ qunlock(&audio); nexterror(); } | |
| 1995/0119 | while(audio.active) waitaudio(); setempty(); | |
| 1995/0214 | poperror(); qunlock(&audio); | |
| 1995/0119 | } break; } | |
| 1995/0119/sys/src/9/port/devaudio.c:640,645 – 1995/0214/sys/src/9/port/devaudio.c:701,711 | ||
| 1995/0119 | case Qaudio: if(audio.amode != Aread) error(Emode); | |
| 1995/0214 | qlock(&audio); if(waserror()){ qunlock(&audio); nexterror(); } | |
| 1995/0119 | while(n > 0) { b = audio.filling; if(b == 0) { | |
| 1995/0119/sys/src/9/port/devaudio.c:665,670 – 1995/0214/sys/src/9/port/devaudio.c:731,738 | ||
| 1995/0119 | putbuf(&audio.empty, b); } } | |
| 1995/0214 | poperror(); qunlock(&audio); | |
| 1995/0119 | break; case Qvolume: | |
| 1995/0119/sys/src/9/port/devaudio.c:770,775 – 1995/0214/sys/src/9/port/devaudio.c:838,848 | ||
| 1995/0119 | case Qaudio: if(audio.amode != Awrite) error(Emode); | |
| 1995/0214 | qlock(&audio); if(waserror()){ qunlock(&audio); nexterror(); } | |
| 1995/0119 | while(n > 0) { b = audio.filling; if(b == 0) { | |
| 1995/0119/sys/src/9/port/devaudio.c:796,801 – 1995/0214/sys/src/9/port/devaudio.c:869,876 | ||
| 1995/0119 | putbuf(&audio.full, b); } } | |
| 1995/0214 | poperror(); qunlock(&audio); | |
| 1995/0119 | break; } return n0 - n; | |
| 1995/0119/sys/src/9/port/devaudio.c:829,834 – 1995/0214/sys/src/9/port/devaudio.c:904,911 | ||
| 1995/0119 | { ulong *p, *ep, b; | |
| 1995/0214 | if(!SBswab) return; | |
| 1995/0119 | p = (ulong*)a; ep = p + (Bufsize>>2); while(p < ep) { | |
| 1995/0214/sys/src/9/port/devaudio.c:81,87 – 1995/0215/sys/src/9/port/devaudio.c:81,86 (short | long) | ||
| 1995/0119 | int speed; /* pcm sample rate, doesnt change w stereo */ int major; /* SB16 major version number (sb 4) */ int minor; /* SB16 minor version number */ | |
| 1995/0215/sys/src/9/port/devaudio.c:430,436 – 1995/0216/sys/src/9/port/devaudio.c:430,436 (short | long) | ||
| 1995/0119 | pokeaudio(); tsleep(&audio.vous, anybuf, 0, 10*1000); if(audio.intr == 0) { | |
| 1995/0214 |
| |
| 1995/0216 | /* print("audio timeout\n"); /**/ | |
| 1995/0119 | audio.active = 0; pokeaudio(); } | |
| 1995/0216/sys/src/9/port/devaudio.c:13,18 – 1995/0217/sys/src/9/port/devaudio.c:13,19 (short | long) | ||
| 1995/0119 | #define NPORT (sizeof audiodir/sizeof(Dirtab)) | |
| 1995/0217 | typedef struct AQueue AQueue; | |
| 1995/0119 | typedef struct Buf Buf; typedef struct Level Level; | |
| 1995/0216/sys/src/9/port/devaudio.c:58,64 – 1995/0217/sys/src/9/port/devaudio.c:59,65 | ||
| 1995/0119 | ulong phys; Buf* next; }; | |
| 1995/0217 | struct AQueue | |
| 1995/0119 | { Lock; Buf* first; | |
| 1995/0216/sys/src/9/port/devaudio.c:83,90 – 1995/0217/sys/src/9/port/devaudio.c:84,91 | ||
| 1995/0119 | int minor; /* SB16 minor version number */ Buf buf[Nbuf]; /* buffers and queues */ | |
| 1995/0217 | AQueue empty; AQueue full; | |
| 1995/0119 | Buf* current; Buf* filling; } audio; | |
| 1995/0216/sys/src/9/port/devaudio.c:265,271 – 1995/0217/sys/src/9/port/devaudio.c:266,272 | ||
| 1995/0119 | } static Buf* | |
| 1995/0217 | getbuf(AQueue *q) | |
| 1995/0119 | { Buf *b; | |
| 1995/0216/sys/src/9/port/devaudio.c:279,285 – 1995/0217/sys/src/9/port/devaudio.c:280,286 | ||
| 1995/0119 | } static void | |
| 1995/0217 | putbuf(AQueue *q, Buf *b) | |
| 1995/0119 | { ilock(q); | |
| 1995/0217/sys/src/9/port/devaudio.c:15,21 – 1995/0221/sys/src/9/port/devaudio.c:15,20 (short | long) | ||
| 1995/0119 | ||
| 1995/0217 | typedef struct AQueue AQueue; | |
| 1995/0119 | typedef struct Buf Buf; | |
| 1995/0217/sys/src/9/port/devaudio.c:24,34 – 1995/0221/sys/src/9/port/devaudio.c:23,46 | ||
| 1995/0119 | Qvolume, Fmono = 1, | |
| 1995/0221 | Fin = 2, Fout = 4, | |
| 1995/0119 | ||
| 1995/0214 | Aclosed = 0, Aread, | |
| 1995/0119 | Awrite, | |
| 1995/0221 | Vaudio = 0, Vsynth, Vcd, Vline, Vmic, Vspeaker, Vtreb, Vbass, Vspeed, Nvol, | |
| 1995/0119 | Speed = 44100, Ncmd = 50, /* max volume command words */ }; | |
| 1995/0217/sys/src/9/port/devaudio.c:40,58 – 1995/0221/sys/src/9/port/devaudio.c:52,57 | ||
| 1995/0119 | "volume", {Qvolume}, 0, 0666, }; | |
| 1995/0217/sys/src/9/port/devaudio.c:74,85 – 1995/0221/sys/src/9/port/devaudio.c:73,82 | ||
| 1995/0119 | int active; /* boolean dma running */ int intr; /* boolean an interrupt has happened */ | |
| 1995/0214 | int amode; /* Aclosed/Aread/Awrite for /audio */ | |
| 1995/0119 |
| |
| 1995/0221 | int rivol[Nvol]; /* right/left input/output volumes */ int livol[Nvol]; int rovol[Nvol]; int lovol[Nvol]; | |
| 1995/0119 | int major; /* SB16 major version number (sb 4) */ int minor; /* SB16 minor version number */ | |
| 1995/0217/sys/src/9/port/devaudio.c:93,123 – 1995/0221/sys/src/9/port/devaudio.c:90,111 | ||
| 1995/0119 | static struct { char* name; | |
| 1995/0221 | int ilval; /* initial values */ | |
| 1995/0119 | int irval; } volumes[] = { | |
| 1995/0221 | [Vaudio] "audio", Fout, 50, 50, [Vsynth] "synth", Fin|Fout, 0, 0, [Vcd] "cd", Fin|Fout, 0, 0, [Vline] "line", Fin|Fout, 0, 0, [Vmic] "mic", Fin|Fout|Fmono, 0, 0, [Vspeaker] "speaker", Fout|Fmono, 0, 0, | |
| 1995/0119 |
| |
| 1995/0221 | [Vtreb] "treb", Fout, 50, 50, [Vbass] "bass", Fout, 50, 50, | |
| 1995/0119 |
| |
| 1995/0221 | [Vspeed] "speed", Fin|Fout|Fmono, Speed, Speed, | |
| 1995/0119 | 0 }; | |
| 1995/0217/sys/src/9/port/devaudio.c:229,267 – 1995/0221/sys/src/9/port/devaudio.c:217,284 | ||
| 1995/0119 | static void mxvolume(void) { | |
| 1995/0221 | int *left, *right; int source; if(audio.amode == Aread){ left = audio.livol; right = audio.rivol; }else{ left = audio.lovol; right = audio.rovol; } | |
| 1995/0214 | ilock(&blaster); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmd(0x30, 255); /* left master */ mxcmd(0x31, 255); /* right master */ mxcmd(0x3f, 0); /* left igain */ mxcmd(0x40, 0); /* right igain */ mxcmd(0x41, 0); /* left ogain */ mxcmd(0x42, 0); /* right ogain */ | |
| 1995/0119 |
| |
| 1995/0221 | mxcmds(0x32, left[Vaudio]); mxcmds(0x33, right[Vaudio]); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmds(0x34, left[Vsynth]); mxcmds(0x35, right[Vsynth]); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmds(0x36, left[Vcd]); mxcmds(0x37, right[Vcd]); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmds(0x38, left[Vline]); mxcmds(0x39, right[Vline]); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmds(0x3a, left[Vmic]); mxcmds(0x3b, left[Vspeaker]); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmdu(0x44, left[Vtreb]); mxcmdu(0x45, right[Vtreb]); | |
| 1995/0119 |
| |
| 1995/0221 | mxcmdu(0x46, left[Vbass]); mxcmdu(0x47, right[Vbass]); | |
| 1995/0119 |
| |
| 1995/0221 | source = 0; if(left[Vsynth]) source |= 1<<6; if(right[Vsynth]) source |= 1<<5; if(left[Vaudio]) source |= 1<<4; if(right[Vaudio]) source |= 1<<3; if(left[Vcd]) source |= 1<<2; if(right[Vcd]) source |= 1<<1; if(left[Vmic]) source |= 1<<0; if(audio.amode == Aread) mxcmd(0x3c, 0); /* output switch */ else mxcmd(0x3c, source); mxcmd(0x3d, source); /* input left switch */ mxcmd(0x3e, source); /* input right switch */ | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } | |
| 1995/0217/sys/src/9/port/devaudio.c:337,351 – 1995/0221/sys/src/9/port/devaudio.c:354,372 | ||
| 1995/0119 | startdma(void) { ulong count; | |
| 1995/0221 | int speed; | |
| 1995/0119 | ||
| 1995/0214 | ilock(&blaster); dmaend(Dma); | |
| 1995/0221 | if(audio.amode == Aread) { | |
| 1995/0119 | sbcmd(0x42); /* input sampling rate */ | |
| 1995/0214 |
| |
| 1995/0221 | speed = audio.livol[Vspeed]; } else { | |
| 1995/0119 | sbcmd(0x41); /* output sampling rate */ | |
| 1995/0221 | speed = audio.lovol[Vspeed]; } sbcmd(speed>>8); sbcmd(speed); | |
| 1995/0119 | count = (Bufsize >> 1) - 1; if(audio.amode == Aread) | |
| 1995/0217/sys/src/9/port/devaudio.c:479,486 – 1995/0221/sys/src/9/port/devaudio.c:500,509 | ||
| 1995/0119 | int i; for(i=0; volumes[i].name; i++) { | |
| 1995/0221 | audio.lovol[i] = volumes[i].ilval; audio.rovol[i] = volumes[i].irval; audio.livol[i] = volumes[i].ilval; audio.rivol[i] = volumes[i].irval; | |
| 1995/0119 | } } | |
| 1995/0217/sys/src/9/port/devaudio.c:629,634 – 1995/0221/sys/src/9/port/devaudio.c:652,658 | ||
| 1995/0119 | setempty(); audio.curcount = 0; | |
| 1995/0214 | qunlock(&audio); | |
| 1995/0221 | mxvolume(); | |
| 1995/0119 | break; } c = devopen(c, omode, audiodir, NPORT, devgen); | |
| 1995/0217/sys/src/9/port/devaudio.c:684,691 – 1995/0221/sys/src/9/port/devaudio.c:708,716 | ||
| 1995/0119 | long audioread(Chan *c, char *a, long n, ulong offset) { | |
| 1995/0221 | int liv, riv, lov, rov; long m, n0; char buf[300]; | |
| 1995/0119 | Buf *b; int j; | |
| 1995/0217/sys/src/9/port/devaudio.c:737,754 – 1995/0221/sys/src/9/port/devaudio.c:762,797 | ||
| 1995/0119 | case Qvolume: j = 0; | |
| 1995/0221 | buf[0] = 0; for(m=0; volumes[m].name; m++){ liv = audio.livol[m]; riv = audio.rivol[m]; lov = audio.lovol[m]; rov = audio.rovol[m]; j += snprint(buf+j, sizeof(buf)-j, "%s", volumes[m].name); if((volumes[m].flag & Fmono) || liv==riv && lov==rov){ if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) && liv==lov) j += snprint(buf+j, sizeof(buf)-j, " %d", liv); else{ if(volumes[m].flag & Fin) j += snprint(buf+j, sizeof(buf)-j, " in %d", liv); if(volumes[m].flag & Fout) j += snprint(buf+j, sizeof(buf)-j, " out %d", lov); } }else{ if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) && liv==lov && riv==rov) j += snprint(buf+j, sizeof(buf)-j, " left %d right %d", liv, riv); else{ if(volumes[m].flag & Fin) j += snprint(buf+j, sizeof(buf)-j, " in left %d right %d", liv, riv); if(volumes[m].flag & Fout) j += snprint(buf+j, sizeof(buf)-j, " out left %d right %d", lov, rov); } | |
| 1995/0119 | } | |
| 1995/0221 | j += snprint(buf+j, sizeof(buf)-j, "\n"); | |
| 1995/0119 | } return readstr(offset, a, n, buf); | |
| 1995/0217/sys/src/9/port/devaudio.c:766,772 – 1995/0221/sys/src/9/port/devaudio.c:809,815 | ||
| 1995/0119 | audiowrite(Chan *c, char *a, long n, ulong offset) { long m, n0; | |
| 1995/0221 | int i, nf, v, left, right, in, out; | |
| 1995/0119 | char buf[255], *field[Ncmd]; Buf *b; | |
| 1995/0217/sys/src/9/port/devaudio.c:779,787 – 1995/0221/sys/src/9/port/devaudio.c:822,832 | ||
| 1995/0119 | break; case Qvolume: | |
| 1995/0221 | v = Vaudio; | |
| 1995/0119 | left = 1; right = 1; | |
| 1995/0221 | in = 1; out = 1; | |
| 1995/0119 | if(n > sizeof(buf)-1) n = sizeof(buf)-1; memmove(buf, a, n); | |
| 1995/0217/sys/src/9/port/devaudio.c:794,803 – 1995/0221/sys/src/9/port/devaudio.c:839,852 | ||
| 1995/0119 | */ if(field[i][0] >= '0' && field[i][0] <= '9') { m = strtoul(field[i], 0, 10); | |
| 1995/0221 | if(left && out) audio.lovol[v] = m; if(left && in) audio.livol[v] = m; if(right && out) audio.rovol[v] = m; if(right && in) audio.rivol[v] = m; | |
| 1995/0119 | mxvolume(); goto cont0; } | |
| 1995/0217/sys/src/9/port/devaudio.c:805,810 – 1995/0221/sys/src/9/port/devaudio.c:854,863 | ||
| 1995/0119 | for(m=0; volumes[m].name; m++) { if(strcmp(field[i], volumes[m].name) == 0) { v = m; | |
| 1995/0221 | in = 1; out = 1; left = 1; right = 1; | |
| 1995/0119 | goto cont0; } } | |
| 1995/0217/sys/src/9/port/devaudio.c:814,819 – 1995/0221/sys/src/9/port/devaudio.c:867,882 | ||
| 1995/0119 | mxvolume(); goto cont0; } | |
| 1995/0221 | if(strcmp(field[i], "in") == 0) { in = 1; out = 0; goto cont0; } if(strcmp(field[i], "out") == 0) { in = 0; out = 1; goto cont0; } | |
| 1995/0119 | if(strcmp(field[i], "left") == 0) { left = 1; right = 0; | |
| 1995/0217/sys/src/9/port/devaudio.c:821,831 – 1995/0221/sys/src/9/port/devaudio.c:884,889 | ||
| 1995/0119 | } if(strcmp(field[i], "right") == 0) { left = 0; | |
| 1995/0221/sys/src/9/port/devaudio.c:420,428 – 1995/0804/sys/src/9/port/devaudio.c:420,427 (short | long) | ||
| 1995/0119 | } void | |
| 1995/0214 |
| |
| 1995/0804 | pcaudiosbintr(Ureg*, void*) | |
| 1995/0214 | { | |
| 1995/0221/sys/src/9/port/devaudio.c:434,442 – 1995/0804/sys/src/9/port/devaudio.c:433,440 | ||
| 1995/0119 | } static int | |
| 1995/0804 | anybuf(void*) | |
| 1995/0119 | { | |
| 1995/0221/sys/src/9/port/devaudio.c:664,676 – 1995/0804/sys/src/9/port/devaudio.c:662,669 | ||
| 1995/0119 | } void | |
| 1995/0804 | audiocreate(Chan*, char*, int, ulong) | |
| 1995/0119 | { | |
| 1995/0221/sys/src/9/port/devaudio.c:806,812 – 1995/0804/sys/src/9/port/devaudio.c:799,805 | ||
| 1995/0119 | } long | |
| 1995/0804 | audiowrite(Chan *c, char *a, long n, ulong) | |
| 1995/0119 | { long m, n0; | |
| 1995/0221 | int i, nf, v, left, right, in, out; | |
| 1995/0221/sys/src/9/port/devaudio.c:813,820 – 1995/0804/sys/src/9/port/devaudio.c:806,811 | ||
| 1995/0119 | char buf[255], *field[Ncmd]; Buf *b; | |
| 1995/0221/sys/src/9/port/devaudio.c:941,959 – 1995/0804/sys/src/9/port/devaudio.c:932,945 | ||
| 1995/0119 | } void | |
| 1995/0804 | audioremove(Chan*) | |
| 1995/0119 | { | |
| 1995/0804 | audiowstat(Chan*, char*) | |
| 1995/0119 | { | |
| 1995/0804/sys/src/9/port/devaudio.c:7,13 – 1996/0223/sys/src/9/port/devaudio.c:7,12 (short | long) | ||
| 1995/0119 | #include "dat.h" #include "fns.h" #include "../port/error.h" | |
| 1996/0223/sys/src/9/port/devaudio.c:822,828 – 1996/0315/sys/src/9/port/devaudio.c:822,828 (short | long) | ||
| 1995/0119 | memmove(buf, a, n); buf[n] = '\0'; | |
| 1996/0315 | nf = parsefields(buf, field, Ncmd, " \t\n"); | |
| 1995/0119 | for(i = 0; i < nf; i++){ /* * a number is volume | |
| 1996/0315/sys/src/9/port/devaudio.c:121,131 – 1996/1024/sys/src/9/port/devaudio.c:121,132 (short | long) | ||
| 1995/0214 | int clri8; int clri16; int clri401; | |
| 1996/1024 | int dma; | |
| 1995/0214 | } blaster; | |
| 1995/0119 | static void swab(uchar*); | |
| 1995/0214 |
| |
| 1996/1024 | static char Emajor[] = "soundblaster not responding/wrong version"; | |
| 1995/0119 | static char Emode[] = "illegal open mode"; static char Evolume[] = "illegal volume specifier"; | |
| 1996/0315/sys/src/9/port/devaudio.c:334,344 – 1996/1024/sys/src/9/port/devaudio.c:335,345 | ||
| 1995/0119 | if(b == 0) goto shutdown; | |
| 1995/0214 |
| |
| 1996/1024 | dmasetup(blaster.dma, b->virt, Bufsize, audio.amode == Aread); | |
| 1995/0119 | return; shutdown: | |
| 1995/0214 |
| |
| 1996/1024 | dmaend(blaster.dma); | |
| 1995/0119 | sbcmd(0xd9); /* exit at end of count */ sbcmd(0xd5); /* pause */ audio.curcount = 0; | |
| 1996/0315/sys/src/9/port/devaudio.c:356,362 – 1996/1024/sys/src/9/port/devaudio.c:357,363 | ||
| 1995/0221 | int speed; | |
| 1995/0119 | ||
| 1995/0214 | ilock(&blaster); | |
| 1996/1024 | dmaend(blaster.dma); | |
| 1995/0221 | if(audio.amode == Aread) { | |
| 1995/0119 | sbcmd(0x42); /* input sampling rate */ | |
| 1995/0221 | speed = audio.livol[Vspeed]; | |
| 1996/0315/sys/src/9/port/devaudio.c:511,516 – 1996/1024/sys/src/9/port/devaudio.c:512,518 | ||
| 1995/0119 | int i; | |
| 1995/0214 | sbconf.port = 0x220; | |
| 1996/1024 | sbconf.dma = 5; | |
| 1995/0214 | sbconf.irq = 7; if(isaconfig("audio", 0, &sbconf) == 0) return; | |
| 1996/0315/sys/src/9/port/devaudio.c:523,529 – 1996/1024/sys/src/9/port/devaudio.c:525,531 | ||
| 1995/0214 | case 0x280: break; default: | |
| 1996/1024 | print("devaudio: bad sb16 port 0x%x\n", sbconf.port); | |
| 1995/0214 | return; } switch(sbconf.irq){ | |
| 1996/0315/sys/src/9/port/devaudio.c:533,542 – 1996/1024/sys/src/9/port/devaudio.c:535,546 | ||
| 1995/0214 | case 10: break; default: | |
| 1996/1024 | print("devaudio: bad sb16 irq %d\n", sbconf.irq); | |
| 1995/0214 | return; } | |
| 1996/1024 | blaster.dma = sbconf.dma; | |
| 1995/0214 | blaster.reset = sbconf.port + 0x6; blaster.read = sbconf.port + 0xa; blaster.write = sbconf.port + 0xc; | |
| 1996/0315/sys/src/9/port/devaudio.c:548,554 – 1996/1024/sys/src/9/port/devaudio.c:552,558 | ||
| 1995/0214 | blaster.clri16 = sbconf.port + 0xf; blaster.clri401 = sbconf.port + 0x100; | |
| 1995/0119 |
| |
| 1996/1024 | seteisadma(blaster.dma, audiodmaintr); | |
| 1995/0214 | setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0); | |
| 1995/0119 | ||
| 1995/0214 | audio.amode = Aclosed; | |
| 1996/0315/sys/src/9/port/devaudio.c:570,576 – 1996/1024/sys/src/9/port/devaudio.c:574,580 | ||
| 1995/0119 | audio.minor = sbread(); if(audio.major != 4) { | |
| 1996/1024 | print("bad soundblaster model #%.2x #%.2x; not SB 16\n", audio.major, audio.minor); | |
| 1995/0119 | return; } /* | |
| 1996/0315/sys/src/9/port/devaudio.c:588,594 – 1996/1024/sys/src/9/port/devaudio.c:592,598 | ||
| 1995/0214 | (sbconf.irq==7)? 4: (sbconf.irq==10)? 8: | |
| 1995/0119 | 0); | |
| 1996/1024 | mxcmd(0x81, 1<<blaster.dma); /* dma */ | |
| 1995/0119 | } Chan* | |
| 1996/1024/sys/src/9/port/devaudio.c:512,518 – 1996/1025/sys/src/9/port/devaudio.c:512,518 (short | long) | ||
| 1995/0119 | int i; | |
| 1995/0214 | sbconf.port = 0x220; | |
| 1996/1024 |
| |
| 1996/1025 | sbconf.dma = Dma; | |
| 1995/0214 | sbconf.irq = 7; if(isaconfig("audio", 0, &sbconf) == 0) return; | |
| 1996/1025/sys/src/9/port/devaudio.c:10,17 – 1997/0327/sys/src/9/port/devaudio.c:10,15 (short | long) | ||
| 1995/0119 | #include "io.h" #include "audio.h" | |
| 1995/0217 | typedef struct AQueue AQueue; | |
| 1995/0119 | typedef struct Buf Buf; | |
| 1996/1025/sys/src/9/port/devaudio.c:94,103 – 1997/0327/sys/src/9/port/devaudio.c:92,101 | ||
| 1995/0119 | int irval; } volumes[] = { | |
| 1995/0221 |
| |
| 1997/0327 | [Vaudio] "audio", Fout, 50, 50, [Vsynth] "synth", Fin|Fout, 0, 0, [Vcd] "cd", Fin|Fout, 0, 0, [Vline] "line", Fin|Fout, 0, 0, | |
| 1995/0221 | [Vmic] "mic", Fin|Fout|Fmono, 0, 0, [Vspeaker] "speaker", Fout|Fmono, 0, 0, | |
| 1995/0119 | ||
| 1996/1025/sys/src/9/port/devaudio.c:104,111 – 1997/0327/sys/src/9/port/devaudio.c:102,109 | ||
| 1995/0221 | [Vtreb] "treb", Fout, 50, 50, [Vbass] "bass", Fout, 50, 50, | |
| 1995/0119 | ||
| 1995/0221 |
| |
| 1995/0119 |
| |
| 1997/0327 | [Vspeed] "speed", Fin|Fout|Fmono, Speed, Speed, 0 | |
| 1995/0119 | }; | |
| 1995/0214 | static struct | |
| 1996/1025/sys/src/9/port/devaudio.c:142,148 – 1997/0327/sys/src/9/port/devaudio.c:140,146 | ||
| 1995/0119 | return 0; } } | |
| 1997/0327 | /* print("#A: sbcmd (#%.2x) timeout\n", val); /**/ | |
| 1995/0119 | return 1; } | |
| 1996/1025/sys/src/9/port/devaudio.c:157,163 – 1997/0327/sys/src/9/port/devaudio.c:155,161 | ||
| 1995/0214 | return inb(blaster.read); | |
| 1995/0119 | } } | |
| 1997/0327 | /* print("#A: sbread did not respond\n"); /**/ | |
| 1995/0119 | return 0xbb; } | |
| 1996/1025/sys/src/9/port/devaudio.c:422,428 – 1997/0327/sys/src/9/port/devaudio.c:420,426 | ||
| 1995/0119 | void | |
| 1995/0804 | pcaudiosbintr(Ureg*, void*) | |
| 1995/0214 | { | |
| 1997/0327 | /* print("#A: audio interrupt\n"); /**/ | |
| 1995/0214 | audiosbintr(); } | |
| 1996/1025/sys/src/9/port/devaudio.c:429,435 – 1997/0327/sys/src/9/port/devaudio.c:427,433 | ||
| 1995/0214 | void | |
| 1995/0119 | audiodmaintr(void) { | |
| 1997/0327 | /* print("#A: dma interrupt\n"); /**/ | |
| 1995/0119 | } static int | |
| 1996/1025/sys/src/9/port/devaudio.c:450,456 – 1997/0327/sys/src/9/port/devaudio.c:448,454 | ||
| 1995/0119 | pokeaudio(); tsleep(&audio.vous, anybuf, 0, 10*1000); if(audio.intr == 0) { | |
| 1995/0216 |
| |
| 1997/0327 | /* print("#A: audio timeout\n"); /**/ | |
| 1995/0119 | audio.active = 0; pokeaudio(); } | |
| 1996/1025/sys/src/9/port/devaudio.c:487,497 – 1997/0327/sys/src/9/port/devaudio.c:485,490 | ||
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } | |
| 1996/1025/sys/src/9/port/devaudio.c:505,511 – 1997/0327/sys/src/9/port/devaudio.c:498,504 | ||
| 1995/0119 | } } | |
| 1997/0327 | static void | |
| 1995/0119 | audioinit(void) { | |
| 1995/0214 | ISAConf sbconf; | |
| 1996/1025/sys/src/9/port/devaudio.c:525,531 – 1997/0327/sys/src/9/port/devaudio.c:518,524 | ||
| 1995/0214 | case 0x280: break; default: | |
| 1996/1024 |
| |
| 1997/0327 | print("#A: bad port 0x%x\n", sbconf.port); | |
| 1995/0214 | return; } switch(sbconf.irq){ | |
| 1996/1025/sys/src/9/port/devaudio.c:535,546 – 1997/0327/sys/src/9/port/devaudio.c:528,537 | ||
| 1995/0214 | case 10: break; default: | |
| 1996/1024 |
| |
| 1997/0327 | print("#A: bad irq %d\n", sbconf.irq); | |
| 1995/0214 | return; } | |
| 1996/1024 |
| |
| 1995/0214 | blaster.reset = sbconf.port + 0x6; blaster.read = sbconf.port + 0xa; blaster.write = sbconf.port + 0xc; | |
| 1996/1025/sys/src/9/port/devaudio.c:551,556 – 1997/0327/sys/src/9/port/devaudio.c:542,548 | ||
| 1995/0214 | blaster.clri8 = sbconf.port + 0xe; blaster.clri16 = sbconf.port + 0xf; blaster.clri401 = sbconf.port + 0x100; | |
| 1997/0327 | blaster.dma = sbconf.dma; | |
| 1995/0214 | ||
| 1996/1024 | seteisadma(blaster.dma, audiodmaintr); | |
| 1995/0214 | setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0); | |
| 1996/1025/sys/src/9/port/devaudio.c:565,571 – 1997/0327/sys/src/9/port/devaudio.c:557,563 | ||
| 1995/0119 | i = sbread(); if(i != 0xaa) { | |
| 1997/0327 | print("#A: no response #%.2x\n", i); | |
| 1995/0119 | return; } | |
| 1996/1025/sys/src/9/port/devaudio.c:574,580 – 1997/0327/sys/src/9/port/devaudio.c:566,572 | ||
| 1995/0119 | audio.minor = sbread(); if(audio.major != 4) { | |
| 1996/1024 |
| |
| 1997/0327 | print("#A: model #%.2x #%.2x; not SB 16\n", audio.major, audio.minor); | |
| 1995/0119 | return; } /* | |
| 1996/1025/sys/src/9/port/devaudio.c:595,625 – 1997/0327/sys/src/9/port/devaudio.c:587,611 | ||
| 1996/1024 | mxcmd(0x81, 1<<blaster.dma); /* dma */ | |
| 1995/0119 | } | |
| 1997/0327 | static Chan* | |
| 1995/0119 | audioattach(char *param) { return devattach('A', param); } | |
| 1997/0327 | static int | |
| 1995/0119 | audiowalk(Chan *c, char *name) { | |
| 1997/0327 | return devwalk(c, name, audiodir, nelem(audiodir), devgen); | |
| 1995/0119 | } | |
| 1997/0327 | static void | |
| 1995/0119 | audiostat(Chan *c, char *db) { | |
| 1997/0327 | devstat(c, db, audiodir, nelem(audiodir), devgen); | |
| 1995/0119 | } | |
| 1997/0327 | static Chan* | |
| 1995/0119 | audioopen(Chan *c, int omode) { | |
| 1995/0214 | int amode; | |
| 1996/1025/sys/src/9/port/devaudio.c:656,662 – 1997/0327/sys/src/9/port/devaudio.c:642,648 | ||
| 1995/0221 | mxvolume(); | |
| 1995/0119 | break; } | |
| 1997/0327 | c = devopen(c, omode, audiodir, nelem(audiodir), devgen); | |
| 1995/0119 | c->mode = openmode(omode); c->flag |= COPEN; c->offset = 0; | |
| 1996/1025/sys/src/9/port/devaudio.c:664,676 – 1997/0327/sys/src/9/port/devaudio.c:650,656 | ||
| 1995/0119 | return c; } | |
| 1995/0804 |
| |
| 1995/0119 |
| |
| 1997/0327 | static void | |
| 1995/0119 | audioclose(Chan *c) { | |
| 1996/1025/sys/src/9/port/devaudio.c:701,707 – 1997/0327/sys/src/9/port/devaudio.c:681,687 | ||
| 1995/0119 | } } | |
| 1997/0327 | static long | |
| 1995/0119 | audioread(Chan *c, char *a, long n, ulong offset) { | |
| 1995/0221 | int liv, riv, lov, rov; | |
| 1996/1025/sys/src/9/port/devaudio.c:717,723 – 1997/0327/sys/src/9/port/devaudio.c:697,703 | ||
| 1995/0119 | break; case Qdir: | |
| 1997/0327 | return devdirread(c, a, n, audiodir, nelem(audiodir), devgen); | |
| 1995/0119 | case Qaudio: if(audio.amode != Aread) | |
| 1996/1025/sys/src/9/port/devaudio.c:795,807 – 1997/0327/sys/src/9/port/devaudio.c:775,781 | ||
| 1995/0119 | return n0-n; } | |
| 1997/0327 | static long | |
| 1995/0804 | audiowrite(Chan *c, char *a, long n, ulong) | |
| 1995/0119 | { long m, n0; | |
| 1996/1025/sys/src/9/port/devaudio.c:928,951 – 1997/0327/sys/src/9/port/devaudio.c:902,907 | ||
| 1995/0119 | return n0 - n; } | |
| 1995/0804 |
| |
| 1995/0119 |
| |
| 1995/0804 |
| |
| 1995/0119 |
| |
| 1996/1025/sys/src/9/port/devaudio.c:963,965 – 1997/0327/sys/src/9/port/devaudio.c:919,939 | ||
| 1995/0119 | *p++ = b; } } | |
| 1997/0327 | Dev audiodevtab = { devreset, audioinit, audioattach, devclone, audiowalk, audiostat, audioopen, devcreate, audioclose, audioread, devbread, audiowrite, devbwrite, devremove, devwstat, }; | |
| 1997/0327/sys/src/9/port/devaudio.c:921,926 – 1997/0408/sys/src/9/port/devaudio.c:921,929 (short | long) | ||
| 1995/0119 | } | |
| 1997/0327 | Dev audiodevtab = { | |
| 1997/0408 | 'A', "audio", | |
| 1997/0327 | devreset, audioinit, audioattach, | |
| 1997/0408/sys/src/9/port/devaudio.c:120,125 – 1998/0317/sys/src/9/port/devaudio.c:120,128 (short | long) | ||
| 1995/0214 | int clri16; int clri401; | |
| 1996/1024 | int dma; | |
| 1998/0317 | void (*startdma)(void); void (*intr)(void); | |
| 1995/0214 | } blaster; | |
| 1995/0119 | static void swab(uchar*); | |
| 1997/0408/sys/src/9/port/devaudio.c:140,146 – 1998/0317/sys/src/9/port/devaudio.c:143,149 | ||
| 1995/0119 | return 0; } } | |
| 1997/0327 |
| |
| 1998/0317 | /* print("#A: sbcmd (0x%.2x) timeout\n", val); /**/ | |
| 1995/0119 | return 1; } | |
| 1997/0408/sys/src/9/port/devaudio.c:156,164 – 1998/0317/sys/src/9/port/devaudio.c:159,185 | ||
| 1995/0119 | } } | |
| 1997/0327 | /* print("#A: sbread did not respond\n"); /**/ | |
| 1995/0119 |
| |
| 1998/0317 | return -1; | |
| 1995/0119 | } | |
| 1998/0317 | static int ess1688w(int reg, int val) { if(sbcmd(reg) || sbcmd(val)) return 1; return 0; } static int ess1688r(int reg) { if(sbcmd(0xC0) || sbcmd(reg)) return -1; return sbread(); } | |
| 1995/0119 | static int mxcmd(int addr, int val) { | |
| 1997/0408/sys/src/9/port/devaudio.c:321,331 – 1998/0317/sys/src/9/port/devaudio.c:342,352 | ||
| 1995/0119 | b = audio.current; if(audio.amode == Aread) { | |
| 1998/0317 | if(b) /* shouldn't happen */ | |
| 1995/0119 | putbuf(&audio.full, b); b = getbuf(&audio.empty); } else { | |
| 1998/0317 | if(b) /* shouldn't happen */ | |
| 1995/0119 | putbuf(&audio.empty, b); b = getbuf(&audio.full); } | |
| 1997/0408/sys/src/9/port/devaudio.c:333,340 – 1998/0317/sys/src/9/port/devaudio.c:354,363 | ||
| 1995/0119 | if(b == 0) goto shutdown; | |
| 1996/1024 |
| |
| 1995/0119 |
| |
| 1998/0317 | if(dmasetup(blaster.dma, b->virt, Bufsize, audio.amode == Aread) >= 0) return; print("#A: dmasetup fail\n"); putbuf(&audio.empty, b); | |
| 1995/0119 | shutdown: | |
| 1996/1024 | dmaend(blaster.dma); | |
| 1997/0408/sys/src/9/port/devaudio.c:349,355 – 1998/0317/sys/src/9/port/devaudio.c:372,378 | ||
| 1995/0119 | * start first dma */ static void | |
| 1998/0317 | sb16startdma(void) | |
| 1995/0119 | { ulong count; | |
| 1995/0221 | int speed; | |
| 1997/0408/sys/src/9/port/devaudio.c:380,385 – 1998/0317/sys/src/9/port/devaudio.c:403,499 | ||
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } | |
| 1998/0317 | static int ess1688reset(void) { int i; outb(blaster.reset, 3); delay(1); /* >3 υs */ outb(blaster.reset, 0); delay(1); i = sbread(); if(i != 0xAA) { print("#A: no response 0x%.2x\n", i); return 1; } if(sbcmd(0xC6)){ /* extended mode */ print("#A: barf 3\n"); return 1; } return 0; } static void ess1688startdma(void) { ulong count; int speed, x; ilock(&blaster); dmaend(blaster.dma); if(audio.amode == Awrite) ess1688reset(); if(audio.amode == Aread) sbcmd(0xD3); /* speaker off */ /* * Set the speed. */ if(audio.amode == Aread) speed = audio.livol[Vspeed]; else speed = audio.lovol[Vspeed]; if(speed < 4000) speed = 4000; else if(speed > 48000) speed = 48000; if(speed > 22000) x = 0x80|(256-(795500+speed/2)/speed); else x = 128-(397700+speed/2)/speed; ess1688w(0xA1, x & 0xFF); speed = (speed * 9) / 20; x = 256 - 7160000 / (speed * 82); ess1688w(0xA2, x & 0xFF); if(audio.amode == Aread) ess1688w(0xB8, 0x0E); /* A/D, autoinit */ else ess1688w(0xB8, 0x04); /* D/A, autoinit */ x = ess1688r(0xA8) & ~0x03; ess1688w(0xA8, x|0x01); /* 2 channels */ ess1688w(0xB9, 2); /* demand mode, 4 bytes per request */ if(audio.amode == Awrite) ess1688w(0xB6, 0); ess1688w(0xB7, 0x71); ess1688w(0xB7, 0xBC); x = ess1688r(0xB1) & 0x0F; ess1688w(0xB1, x|0x50); x = ess1688r(0xB2) & 0x0F; ess1688w(0xB2, x|0x50); if(audio.amode == Awrite) sbcmd(0xD1); /* speaker on */ count = -Bufsize; ess1688w(0xA4, count & 0xFF); ess1688w(0xA5, (count>>8) & 0xFF); x = ess1688r(0xB8); ess1688w(0xB8, x|0x05); audio.active = 1; contindma(); iunlock(&blaster); } | |
| 1995/0119 | /* * if audio is stopped, * start it up again. | |
| 1997/0408/sys/src/9/port/devaudio.c:388,398 – 1998/0317/sys/src/9/port/devaudio.c:502,512 | ||
| 1995/0119 | pokeaudio(void) { if(!audio.active) | |
| 1998/0317 | blaster.startdma(); | |
| 1995/0119 | } | |
| 1998/0317 | static void sb16intr(void) | |
| 1995/0119 | { int stat, dummy; | |
| 1997/0408/sys/src/9/port/devaudio.c:417,427 – 1998/0317/sys/src/9/port/devaudio.c:531,570 | ||
| 1995/0119 | } } | |
| 1998/0317 | static void ess1688intr(void) { int dummy; if(audio.active){ ilock(&blaster); contindma(); dummy = inb(blaster.clri8); iunlock(&blaster); audio.intr = 1; wakeup(&audio.vous); USED(dummy); } else print("#A: unexpected ess1688 interrupt\n"); } | |
| 1995/0119 | void | |
| 1998/0317 | audiosbintr(void) { /* * Carrera interrupt interface. */ blaster.intr(); } static void | |
| 1995/0804 | pcaudiosbintr(Ureg*, void*) | |
| 1995/0214 | { | |
| 1997/0327 |
| |
| 1995/0214 |
| |
| 1998/0317 | /* * x86 interrupt interface. */ blaster.intr(); | |
| 1995/0214 | } void | |
| 1997/0408/sys/src/9/port/devaudio.c:498,503 – 1998/0317/sys/src/9/port/devaudio.c:641,708 | ||
| 1995/0119 | } } | |
| 1998/0317 | static int ess1688(ISAConf* sbconf) { int i, major, minor; /* * Try for ESS1688. */ sbcmd(0xE7); /* get version */ major = sbread(); minor = sbread(); if(major != 0x68 || minor != 0x8B){ print("#A: model 0x%.2x 0x%.2x; not ESS1688 compatible\n", major, minor); return 1; } ess1688reset(); switch(sbconf->irq){ case 2: case 9: i = 0x50|(0<<2); break; case 5: i = 0x50|(1<<2); break; case 7: i = 0x50|(2<<2); break; case 10: i = 0x50|(3<<2); break; default: print("#A: bad ESS1688 irq %d\n", sbconf->irq); return 1; } ess1688w(0xB1, i); switch(sbconf->dma){ case 0: i = 0x50|(1<<2); break; case 1: i = 0xF0|(2<<2); break; case 3: i = 0x50|(3<<2); break; default: print("#A: bad ESS1688 dma %d\n", sbconf->dma); return 1; } ess1688w(0xB2, i); ess1688reset(); blaster.startdma = ess1688startdma; blaster.intr = ess1688intr; return 0; } | |
| 1997/0327 | static void | |
| 1995/0119 | audioinit(void) { | |
| 1997/0408/sys/src/9/port/devaudio.c:509,515 – 1998/0317/sys/src/9/port/devaudio.c:714,720 | ||
| 1995/0214 | sbconf.irq = 7; if(isaconfig("audio", 0, &sbconf) == 0) return; | |
| 1998/0317 | if(cistrcmp(sbconf.type, "sb16") != 0 && cistrcmp(sbconf.type, "ess1688") != 0) | |
| 1995/0214 | return; switch(sbconf.port){ case 0x220: | |
| 1997/0408/sys/src/9/port/devaudio.c:544,549 – 1998/0317/sys/src/9/port/devaudio.c:749,757 | ||
| 1995/0214 | blaster.clri401 = sbconf.port + 0x100; | |
| 1997/0327 | blaster.dma = sbconf.dma; | |
| 1995/0214 | ||
| 1998/0317 | blaster.startdma = sb16startdma; blaster.intr = sb16intr; | |
| 1996/1024 | seteisadma(blaster.dma, audiodmaintr); | |
| 1995/0214 | setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0); | |
| 1995/0119 | ||
| 1997/0408/sys/src/9/port/devaudio.c:566,574 – 1998/0317/sys/src/9/port/devaudio.c:774,787 | ||
| 1995/0119 | audio.minor = sbread(); if(audio.major != 4) { | |
| 1997/0327 |
| |
| 1995/0119 |
| |
| 1998/0317 | if(audio.major != 3 || audio.minor != 1 || ess1688(&sbconf)){ print("#A: model 0x%.2x 0x%.2x; not SB 16 compatible\n", audio.major, audio.minor); return; } audio.major = 4; | |
| 1995/0119 | } | |
| 1998/0317 | ||
| 1995/0119 | /* * initialize the mixer */ | |
| 1998/0317/sys/src/9/port/devaudio.c:895,901 – 1998/0319/sys/src/9/port/devaudio.c:895,901 (short | long) | ||
|
Change dev read and write to use vlong offset.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1995/0119 | } | |
| 1997/0327 | static long | |
| 1995/0119 |
| |
| 1998/0319 | audioread(Chan *c, char *a, long n, vlong off) | |
| 1995/0119 | { | |
| 1995/0221 | int liv, riv, lov, rov; long m, n0; | |
| 1998/0317/sys/src/9/port/devaudio.c:902,907 – 1998/0319/sys/src/9/port/devaudio.c:902,908 | ||
| 1995/0221 | char buf[300]; | |
| 1995/0119 | Buf *b; int j; | |
| 1998/0319 | ulong offset = off; | |
| 1995/0119 | n0 = n; switch(c->qid.path & ~CHDIR) { | |
| 1998/0317/sys/src/9/port/devaudio.c:989,995 – 1998/0319/sys/src/9/port/devaudio.c:990,996 | ||
| 1995/0119 | } | |
| 1997/0327 | static long | |
| 1995/0804 |
| |
| 1998/0319 | audiowrite(Chan *c, char *a, long n, vlong) | |
| 1995/0119 | { long m, n0; | |
| 1995/0221 | int i, nf, v, left, right, in, out; | |
| 1998/0319/sys/src/9/port/devaudio.c:964,983 – 1998/0327/sys/src/9/port/devaudio.c:964,989 (short | long) | ||
|
Formatting edits.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1995/0221 | j += snprint(buf+j, sizeof(buf)-j, " %d", liv); else{ if(volumes[m].flag & Fin) | |
| 1998/0327 | j += snprint(buf+j, sizeof(buf)-j, " in %d", liv); | |
| 1995/0221 | if(volumes[m].flag & Fout) | |
| 1998/0327 | j += snprint(buf+j, sizeof(buf)-j, " out %d", lov); | |
| 1995/0221 | } }else{ | |
| 1998/0327 | if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) && liv==lov && riv==rov) j += snprint(buf+j, sizeof(buf)-j, " left %d right %d", | |
| 1995/0221 | liv, riv); else{ if(volumes[m].flag & Fin) | |
| 1998/0327 | j += snprint(buf+j, sizeof(buf)-j, " in left %d right %d", | |
| 1995/0221 | liv, riv); if(volumes[m].flag & Fout) | |
| 1998/0327 | j += snprint(buf+j, sizeof(buf)-j, " out left %d right %d", | |
| 1995/0221 | lov, rov); } | |
| 1995/0119 | } | |
| 1998/0327/sys/src/9/port/devaudio.c:965,974 – 1998/0331/sys/src/9/port/devaudio.c:965,974 (short | long) | ||
|
Whitespace edit.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1995/0221 | else{ if(volumes[m].flag & Fin) | |
| 1998/0327 | j += snprint(buf+j, sizeof(buf)-j, | |
| 1998/0331 | " in %d", liv); | |
| 1995/0221 | if(volumes[m].flag & Fout) | |
| 1998/0327 | j += snprint(buf+j, sizeof(buf)-j, | |
| 1998/0331 | " out %d", lov); | |
| 1995/0221 | } }else{ | |
| 1998/0327 | if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) && | |
| 1998/0331/sys/src/9/port/devaudio.c:781,787 – 1998/0512/sys/src/9/port/devaudio.c:781,787 (short | long) | ||
|
Whitespace edit.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1998/0317 | } audio.major = 4; | |
| 1995/0119 | } | |
| 1998/0317 | ||
| 1998/0512 | ||
| 1995/0119 | /* * initialize the mixer */ | |
| 1998/0512/sys/src/9/port/devaudio.c:879,884 – 1998/0603/sys/src/9/port/devaudio.c:879,896 (short | long) | ||
|
Bug fix: flush final partial buffer on close of write fd.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1995/0119 | case Qaudio: if(c->flag & COPEN) { | |
| 1995/0214 | qlock(&audio); | |
| 1998/0603 | if (audio.amode == Awrite) { /* flush out last partial buffer */ Buf *b = audio.filling; if (b) { audio.filling = 0; memset(b->virt, 0, Bufsize-audio.curcount); swab(b->virt); putbuf(&audio.full, b); } if (!audio.active && audio.full.first) pokeaudio(); } | |
| 1995/0214 | audio.amode = Aclosed; if(waserror()){ qunlock(&audio); | |
| 1998/0603/sys/src/9/port/devaudio.c:866,871 – 1998/0624/sys/src/9/port/devaudio.c:866,872 (short | long) | ||
|
Formatting edit.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1997/0327 | static void | |
| 1995/0119 | audioclose(Chan *c) { | |
| 1998/0624 | Buf *b; | |
| 1995/0119 | switch(c->qid.path & ~CHDIR) { default: | |
| 1998/0603/sys/src/9/port/devaudio.c:879,894 – 1998/0624/sys/src/9/port/devaudio.c:880,895 | ||
| 1995/0119 | case Qaudio: if(c->flag & COPEN) { | |
| 1995/0214 | qlock(&audio); | |
| 1998/0603 |
| |
| 1998/0624 | if(audio.amode == Awrite) { | |
| 1998/0603 | /* flush out last partial buffer */ | |
| 1998/0624 | b = audio.filling; if(b) { | |
| 1998/0603 | audio.filling = 0; memset(b->virt, 0, Bufsize-audio.curcount); swab(b->virt); putbuf(&audio.full, b); } | |
| 1998/0624 | if(!audio.active && audio.full.first) | |
| 1998/0603 | pokeaudio(); } | |
| 1995/0214 | audio.amode = Aclosed; | |
| 1998/0624/sys/src/9/port/devaudio.c:674,680 – 1998/0825/sys/src/9/port/devaudio.c:674,680 (short | long) | ||
|
Bug fix: print format.
rsc Fri Mar 4 12:44:25 2005 | ||
| 1998/0317 | i = 0x50|(3<<2); break; default: | |
| 1998/0825 | print("#A: bad ESS1688 irq %lud\n", sbconf->irq); | |
| 1998/0317 | return 1; } ess1688w(0xB1, i); | |
| 1998/0624/sys/src/9/port/devaudio.c:690,696 – 1998/0825/sys/src/9/port/devaudio.c:690,696 | ||
| 1998/0317 | i = 0x50|(3<<2); break; default: | |
| 1998/0825 | print("#A: bad ESS1688 dma %lud\n", sbconf->dma); | |
| 1998/0317 | return 1; } ess1688w(0xB2, i); | |
| 1998/0624/sys/src/9/port/devaudio.c:723,729 – 1998/0825/sys/src/9/port/devaudio.c:723,729 | ||
| 1995/0214 | case 0x280: break; default: | |
| 1997/0327 |
| |
| 1998/0825 | print("#A: bad port 0x%lux\n", sbconf.port); | |
| 1995/0214 | return; } switch(sbconf.irq){ | |
| 1998/0624/sys/src/9/port/devaudio.c:733,739 – 1998/0825/sys/src/9/port/devaudio.c:733,739 | ||
| 1995/0214 | case 10: break; default: | |
| 1997/0327 |
| |
| 1998/0825 | print("#A: bad irq %lud\n", sbconf.irq); | |
| 1995/0214 | return; } | |
| 1998/0825/sys/src/9/port/devaudio.c:885,891 – 1999/0219/sys/src/9/port/devaudio.c:885,891 (short | long) | ||
| 1998/0624 | b = audio.filling; if(b) { | |
| 1998/0603 | audio.filling = 0; | |
| 1999/0219 | memset(b->virt+audio.curcount, 0, Bufsize-audio.curcount); | |
| 1998/0603 | swab(b->virt); putbuf(&audio.full, b); } | |
| 1999/0219/sys/src/9/port/devaudio.c:908,914 – 1999/0320/sys/src/9/port/devaudio.c:908,914 (short | long) | ||
| 1995/0119 | } | |
| 1997/0327 | static long | |
| 1998/0319 |
| |
| 1999/0320 | audioread(Chan *c, void *v, long n, vlong off) | |
| 1995/0119 | { | |
| 1995/0221 | int liv, riv, lov, rov; long m, n0; | |
| 1999/0219/sys/src/9/port/devaudio.c:916,923 – 1999/0320/sys/src/9/port/devaudio.c:916,925 | ||
| 1995/0119 | Buf *b; int j; | |
| 1998/0319 | ulong offset = off; | |
| 1999/0320 | char *a; | |
| 1995/0119 | n0 = n; | |
| 1999/0320 | a = v; | |
| 1995/0119 | switch(c->qid.path & ~CHDIR) { default: error(Eperm); | |
| 1999/0219/sys/src/9/port/devaudio.c:1009,1021 – 1999/0320/sys/src/9/port/devaudio.c:1011,1025 | ||
| 1995/0119 | } | |
| 1997/0327 | static long | |
| 1998/0319 |
| |
| 1999/0320 | audiowrite(Chan *c, void *vp, long n, vlong) | |
| 1995/0119 | { long m, n0; | |
| 1995/0221 | int i, nf, v, left, right, in, out; | |
| 1995/0119 | char buf[255], *field[Ncmd]; Buf *b; | |
| 1999/0320 | char *a; | |
| 1995/0119 | ||
| 1999/0320 | a = vp; | |
| 1995/0119 | n0 = n; switch(c->qid.path & ~CHDIR) { default: | |
| 1999/0320/sys/src/9/port/devaudio.c:711,717 – 1999/0504/sys/src/9/port/devaudio.c:711,717 (short | long) | ||
| 1995/0119 | ||
| 1995/0214 | sbconf.port = 0x220; | |
| 1996/1025 | sbconf.dma = Dma; | |
| 1995/0214 |
| |
| 1999/0504 | sbconf.irq = IrqAUDIO; | |
| 1995/0214 | if(isaconfig("audio", 0, &sbconf) == 0) return; | |
| 1998/0317 | if(cistrcmp(sbconf.type, "sb16") != 0 && cistrcmp(sbconf.type, "ess1688") != 0) | |
| 1999/0504/sys/src/9/port/devaudio.c:18,23 – 1999/1005/sys/src/9/port/devaudio.c:18,24 (short | long) | ||
| 1995/0119 | Qdir = 0, Qaudio, Qvolume, | |
| 1999/1005 | Qstatus, | |
| 1995/0119 | Fmono = 1, | |
| 1995/0221 | Fin = 2, | |
| 1999/0504/sys/src/9/port/devaudio.c:47,52 – 1999/1005/sys/src/9/port/devaudio.c:48,54 | ||
| 1995/0119 | { "audio", {Qaudio}, 0, 0666, "volume", {Qvolume}, 0, 0666, | |
| 1999/1005 | "audiostat",{Qstatus}, 0, 0444, | |
| 1995/0119 | }; struct Buf | |
| 1999/0504/sys/src/9/port/devaudio.c:76,81 – 1999/1005/sys/src/9/port/devaudio.c:78,85 | ||
| 1995/0221 | int lovol[Nvol]; | |
| 1995/0119 | int major; /* SB16 major version number (sb 4) */ int minor; /* SB16 minor version number */ | |
| 1999/1005 | ulong totcount; /* how many bytes processed since open */ vlong tottime; /* time at which totcount bytes were processed */ | |
| 1995/0119 | Buf buf[Nbuf]; /* buffers and queues */ | |
| 1995/0217 | AQueue empty; | |
| 1999/0504/sys/src/9/port/devaudio.c:399,404 – 1999/1005/sys/src/9/port/devaudio.c:403,409 | ||
| 1995/0119 | sbcmd(count>>8); audio.active = 1; | |
| 1999/1005 | audio.tottime = todget(nil); | |
| 1995/0119 | contindma(); | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } | |
| 1999/0504/sys/src/9/port/devaudio.c:490,495 – 1999/1005/sys/src/9/port/devaudio.c:495,501 | ||
| 1998/0317 | ess1688w(0xB8, x|0x05); audio.active = 1; | |
| 1999/1005 | audio.tottime = todget(nil); | |
| 1998/0317 | contindma(); iunlock(&blaster); } | |
| 1999/0504/sys/src/9/port/devaudio.c:516,521 – 1999/1005/sys/src/9/port/devaudio.c:522,529 | ||
| 1995/0119 | if(stat & 2) { | |
| 1995/0214 | ilock(&blaster); dummy = inb(blaster.clri16); | |
| 1999/1005 | audio.totcount += Bufsize; audio.tottime = todget(nil); | |
| 1995/0119 | contindma(); | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | audio.intr = 1; | |
| 1999/0504/sys/src/9/port/devaudio.c:538,543 – 1999/1005/sys/src/9/port/devaudio.c:546,553 | ||
| 1998/0317 | if(audio.active){ ilock(&blaster); | |
| 1999/1005 | audio.totcount += Bufsize; audio.tottime = todget(nil); | |
| 1998/0317 | contindma(); dummy = inb(blaster.clri8); iunlock(&blaster); | |
| 1999/0504/sys/src/9/port/devaudio.c:625,630 – 1999/1005/sys/src/9/port/devaudio.c:635,642 | ||
| 1995/0119 | audio.filling = 0; for(i=0; i<Nbuf; i++) putbuf(&audio.empty, &audio.buf[i]); | |
| 1999/1005 | audio.totcount = 0; audio.tottime = 0LL; | |
| 1995/0214 | iunlock(&blaster); | |
| 1995/0119 | } | |
| 1999/0504/sys/src/9/port/devaudio.c:707,713 – 1999/1005/sys/src/9/port/devaudio.c:719,726 | ||
| 1995/0119 | audioinit(void) { | |
| 1995/0214 | ISAConf sbconf; | |
| 1995/0119 |
| |
| 1999/1005 | int i, x; static int irq[] = {2,5,7,10}; | |
| 1995/0119 | ||
| 1995/0214 | sbconf.port = 0x220; | |
| 1996/1025 | sbconf.dma = Dma; | |
| 1999/0504/sys/src/9/port/devaudio.c:752,760 – 1999/1005/sys/src/9/port/devaudio.c:765,770 | ||
| 1998/0317 | blaster.startdma = sb16startdma; blaster.intr = sb16intr; | |
| 1996/1024 |
| |
| 1995/0214 |
| |
| 1995/0119 | ||
| 1995/0214 | audio.amode = Aclosed; | |
| 1995/0119 | resetlevel(); | |
| 1999/0504/sys/src/9/port/devaudio.c:789,795 – 1999/1005/sys/src/9/port/devaudio.c:799,811 | ||
| 1995/0119 | mxvolume(); /* | |
| 1999/1005 | * Attempt to set IRQ/DMA channels. * On old ISA boards, these registers are writable. * On Plug-n-Play boards, these are read-only. * * To accomodate both, we write to the registers, * but then use the contents in case the write is * disallowed. | |
| 1995/0119 | */ mxcmd(0x80, /* irq */ | |
| 1995/0214 | (sbconf.irq==2)? 1: | |
| 1999/0504/sys/src/9/port/devaudio.c:798,803 – 1999/1005/sys/src/9/port/devaudio.c:814,836 | ||
| 1995/0214 | (sbconf.irq==10)? 8: | |
| 1995/0119 | 0); | |
| 1996/1024 | mxcmd(0x81, 1<<blaster.dma); /* dma */ | |
| 1999/1005 | x = mxread(0x81); for(i=5; i<=7; i++) if(x & (1<<i)){ blaster.dma = i; break; } x = mxread(0x80); for(i=0; i<=3; i++) if(x & (1<<i)){ sbconf.irq = irq[i]; break; } seteisadma(blaster.dma, audiodmaintr); setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0); | |
| 1995/0119 | } | |
| 1997/0327 | static Chan* | |
| 1999/0504/sys/src/9/port/devaudio.c:831,836 – 1999/1005/sys/src/9/port/devaudio.c:864,872 | ||
| 1995/0119 | error(Eperm); break; | |
| 1999/1005 | case Qstatus: if((omode&7) != OREAD) error(Eperm); | |
| 1995/0119 | case Qvolume: case Qdir: break; | |
| 1999/0504/sys/src/9/port/devaudio.c:875,880 – 1999/1005/sys/src/9/port/devaudio.c:911,917 | ||
| 1995/0119 | case Qdir: case Qvolume: | |
| 1999/1005 | case Qstatus: | |
| 1995/0119 | break; case Qaudio: | |
| 1999/0504/sys/src/9/port/devaudio.c:965,970 – 1999/1005/sys/src/9/port/devaudio.c:1002,1013 | ||
| 1995/0214 | qunlock(&audio); | |
| 1995/0119 | break; | |
| 1999/1005 | case Qstatus: buf[0] = 0; snprint(buf, sizeof(buf), "bytes %lud\ntime %lld\n", audio.totcount, audio.tottime); return readstr(offset, a, n, buf); | |
| 1995/0119 | case Qvolume: j = 0; | |
| 1995/0221 | buf[0] = 0; | |
| 1999/0504/sys/src/9/port/devaudio.c:1004,1010 – 1999/1005/sys/src/9/port/devaudio.c:1047,1052 | ||
| 1995/0119 | } | |
| 1995/0221 | j += snprint(buf+j, sizeof(buf)-j, "\n"); | |
| 1995/0119 | } | |
| 1999/1005/sys/src/9/port/devaudio.c:743,748 – 1999/1015/sys/src/9/port/devaudio.c:743,749 (short | long) | ||
| 1995/0214 | case 2: case 5: case 7: | |
| 1999/1015 | case 9: | |
| 1995/0214 | case 10: break; default: | |
| Too many diffs (26 > 25). Stopping. | ||