| plan 9 kernel history: overview | file list | diff list |
1995/0214/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 | prev | next) | ||
| 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) { | |