## diffname port/devaudio.c 1995/0119
## diff -e /dev/null /n/fornaxdump/1995/0119/sys/src/brazil/port/devaudio.c
0a
/*
* SB 16 driver
*/
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "../port/error.h"
#include "devtab.h"
#include "io.h"
#include "audio.h"
#define nelem(x) (sizeof (x)/sizeof(x[0]))
#define NPORT (sizeof audiodir/sizeof(Dirtab))
typedef struct Buf Buf;
typedef struct Level Level;
enum
{
Qdir = 0,
Qaudio,
Qvolume,
Fmono = 1,
Aread = 0,
Awrite,
Speed = 44100,
Ncmd = 50, /* max volume command words */
};
Dirtab
audiodir[] =
{
"audio", {Qaudio}, 0, 0666,
"volume", {Qvolume}, 0, 0666,
};
struct Level
{
int master; /* mixer output volume control */
int ogain; /* extra gain after master */
int pcm; /* mixer volume on D/A (voice) */
int synth; /* mixer volume on synthesizer (MIDI) */
int cd; /* mixer volume on cd */
int line; /* mixer volume on line */
int igain; /* mixer volume to A/D */
int treb; /* treb control */
int bass; /* bass control */
int iswitch; /* input on/off switches */
};
struct Buf
{
uchar* virt;
ulong phys;
Buf* next;
};
struct Queue
{
Lock;
Buf* first;
Buf* last;
};
static struct
{
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 */
int amode; /* Aread/Awrite for /audio */
Level left; /* all of left volumes */
Level right; /* all of right volumes */
int mic; /* mono level */
int speaker; /* mono level */
int oswitch; /* output on/off switches */
int speed; /* pcm sample rate, doesnt change w stereo */
int major; /* SB16 major version number (sb 4) */
int minor; /* SB16 minor version number */
char place[20]; /* static place to decode words */
Buf buf[Nbuf]; /* buffers and queues */
Queue empty;
Queue full;
Buf* current;
Buf* filling;
} audio;
static struct
{
char* name;
int* ptr1;
int* ptr2;
int flag;
int ilval;
int irval;
} volumes[] =
{
"master", &audio.left.master, &audio.right.master, 0, 50, 50,
"ogain", &audio.left.ogain, &audio.right.ogain, 0, 0, 0,
"igain", &audio.left.igain, &audio.right.igain, 0, 0, 0,
"treb", &audio.left.treb, &audio.right.treb, 0, 50, 50,
"bass", &audio.left.bass, &audio.right.bass, 0, 50, 50,
"pcm", &audio.left.pcm, &audio.right.pcm, 0, 90, 90,
"synth", &audio.left.synth, &audio.right.synth, 0, 90, 90,
"cd", &audio.left.cd, &audio.right.cd, 0, 81, 81,
"line", &audio.left.line, &audio.right.line, 0, 65, 65,
"mic", &audio.mic, &audio.mic, Fmono, 0, 0,
"speaker", &audio.speaker, &audio.speaker, Fmono, 0, 0,
"oswitch", &audio.oswitch, &audio.oswitch, Fmono, 31, 31,
"iswitch", &audio.left.iswitch, &audio.right.iswitch, 0, 85, 43,
"speed", &audio.speed, &audio.speed, Fmono, Speed, Speed,
0
};
static void swab(uchar*);
static char Emajor[] = "SB16 version too old";
static char Emode[] = "illegal open mode";
static char Evolume[] = "illegal volume specifier";
static int
sbcmd(int val)
{
int i, s;
for(i=1<<16; i!=0; i--) {
s = inb(PORT_WSTATUS);
if((s & 0x80) == 0) {
outb(PORT_WRITE, val);
return 0;
}
}
/* print("SB16 sbcmd (#%.2x) timeout\n", val); /**/
return 1;
}
static int
sbread(void)
{
int i, s;
for(i=1<<16; i!=0; i--) {
s = inb(PORT_RSTATUS);
if((s & 0x80) != 0) {
return inb(PORT_READ);
}
}
/* print("SB16 sbread did not respond\n"); /**/
return 0xbb;
}
static int
mxcmd(int addr, int val)
{
outb(PORT_MIXER_ADDR, addr);
outb(PORT_MIXER_DATA, val);
return 1;
}
static int
mxread(int addr)
{
int s;
outb(PORT_MIXER_ADDR, addr);
s = inb(PORT_MIXER_DATA);
return s;
}
static void
mxcmds(int s, int v)
{
if(v > 100)
v = 100;
if(v < 0)
v = 0;
mxcmd(s, (v*255)/100);
}
static void
mxcmdt(int s, int v)
{
if(v > 100)
v = 100;
if(v <= 0)
mxcmd(s, 0);
else
mxcmd(s, 255-100+v);
}
static void
mxcmdu(int s, int v)
{
if(v > 100)
v = 100;
if(v <= 0)
v = 0;
mxcmd(s, 128-50+v);
}
static void
mxvolume(void)
{
ulong sp;
sp = splhi();
mxcmds(0x30, audio.left.master);
mxcmds(0x31, audio.right.master);
mxcmdt(0x32, audio.left.pcm);
mxcmdt(0x33, audio.right.pcm);
mxcmdt(0x34, audio.left.synth);
mxcmdt(0x35, audio.right.synth);
mxcmdt(0x36, audio.left.cd);
mxcmdt(0x37, audio.right.cd);
mxcmdt(0x38, audio.left.line);
mxcmdt(0x39, audio.right.line);
mxcmdt(0x3a, audio.mic);
mxcmdt(0x3b, audio.speaker);
mxcmds(0x3f, audio.left.igain);
mxcmds(0x40, audio.right.igain);
mxcmds(0x41, audio.left.ogain);
mxcmds(0x42, audio.right.ogain);
mxcmdu(0x44, audio.left.treb);
mxcmdu(0x45, audio.right.treb);
mxcmdu(0x46, audio.left.bass);
mxcmdu(0x47, audio.right.bass);
mxcmd(0x3c, audio.oswitch);
mxcmd(0x3d, audio.left.iswitch);
mxcmd(0x3e, audio.right.iswitch);
splx(sp);
}
static Buf*
getbuf(Queue *q)
{
Buf *b;
ilock(q);
b = q->first;
if(b)
q->first = b->next;
iunlock(q);
return b;
}
static void
putbuf(Queue *q, Buf *b)
{
ilock(q);
b->next = 0;
if(q->first)
q->last->next = b;
else
q->first = b;
q->last = b;
iunlock(q);
}
/*
* move the dma to the next buffer
*/
static void
contindma(void)
{
Buf *b;
ulong count, addr;
if(!audio.active)
goto shutdown;
b = audio.current;
if(audio.amode == Aread) {
if(b) /* shouldnt happen */
putbuf(&audio.full, b);
b = getbuf(&audio.empty);
} else {
if(b) /* shouldnt happen */
putbuf(&audio.empty, b);
b = getbuf(&audio.full);
}
audio.current = b;
if(b == 0)
goto shutdown;
addr = b->phys;
count = ((Bufsize) >> 1) - 1;
/* outb(DMA2_WRMASK, 4|(Dma&3)); /* disable dma */
outb(DMA6_LPAGE, (addr>>16) & 0xfe);
outb(DMA2_CLRBP, 0); /* clear ff */
outb(DMA6_ADDRESS, addr>>1);
outb(DMA6_ADDRESS, addr>>9);
outb(DMA2_CLRBP, 0); /* clear ff */
outb(DMA6_COUNT, count);
outb(DMA6_COUNT, count>>8);
outb(DMA2_WRMASK, (Dma&3)); /* enable dma */
return;
shutdown:
outb(DMA2_WRMASK, 4|(Dma&3)); /* disable dma */
sbcmd(0xd9); /* exit at end of count */
sbcmd(0xd5); /* pause */
audio.curcount = 0;
audio.active = 0;
}
/*
* cause sb to get an interrupt per buffer.
* start first dma
*/
static void
startdma(void)
{
ulong count;
outb(DMA2_WRMASK, 4|(Dma&3)); /* disable dma */
if(audio.amode == Aread) {
outb(DMA2_WRMODE, 0x44 | (Dma&3)); /* set mode */
sbcmd(0x42); /* input sampling rate */
} else {
outb(DMA2_WRMODE, 0x48 | (Dma&3)); /* set mode */
sbcmd(0x41); /* output sampling rate */
}
sbcmd(audio.speed>>8);
sbcmd(audio.speed);
count = (Bufsize >> 1) - 1;
if(audio.amode == Aread)
sbcmd(0xbe); /* A/D, autoinit */
else
sbcmd(0xb6); /* D/A, autoinit */
sbcmd(0x30); /* stereo, 16 bit */
sbcmd(count);
sbcmd(count>>8);
audio.active = 1;
contindma();
}
/*
* if audio is stopped,
* start it up again.
*/
static void
pokeaudio(void)
{
ulong sp;
sp = splhi();
if(!audio.active)
startdma();
splx(sp);
}
void
audiosbintr(void)
{
int stat, dummy;
stat = mxread(0x82) & 7; /* get irq status */
if(stat) {
dummy = 0;
if(stat & 2) {
dummy = inb(PORT_CLRI16);
contindma();
audio.intr = 1;
wakeup(&audio.vous);
}
if(stat & 1) {
dummy = inb(PORT_CLRI8);
}
if(stat & 4) {
dummy = inb(PORT_CLRI401);
}
USED(dummy);
}
}
void
audiodmaintr(void)
{
/* print("sb16 dma interrupt\n"); /**/
}
static int
anybuf(void *p)
{
USED(p);
return audio.intr;
}
/*
* wait for some output to get
* empty buffers back.
*/
static void
waitaudio(void)
{
audio.intr = 0;
pokeaudio();
tsleep(&audio.vous, anybuf, 0, 10*1000);
if(audio.intr == 0) {
/* print("audio timeout\n"); /**/
audio.active = 0;
pokeaudio();
}
}
static void
sbbufinit(void)
{
int i;
void *p;
for(i=0; i<Nbuf; i++) {
p = xspanalloc(Bufsize, CACHELINESZ, 64*1024);
dcflush(p, Bufsize);
audio.buf[i].virt = UNCACHED(uchar, p);
audio.buf[i].phys = (ulong)PADDR(p);
}
}
static void
setempty(void)
{
int i;
audio.empty.first = 0;
audio.empty.last = 0;
audio.full.first = 0;
audio.full.last = 0;
audio.current = 0;
audio.filling = 0;
for(i=0; i<Nbuf; i++)
putbuf(&audio.empty, &audio.buf[i]);
}
void
audioreset(void)
{
}
static void
resetlevel(void)
{
int i;
for(i=0; volumes[i].name; i++) {
*volumes[i].ptr1 = volumes[i].ilval;
*volumes[i].ptr2 = volumes[i].irval;
}
}
void
audioinit(void)
{
int i;
seteisadma(Dma, audiodmaintr);
resetlevel();
outb(PORT_RESET, 1);
delay(1); /* >3 υs */
outb(PORT_RESET, 0);
delay(1);
i = sbread();
if(i != 0xaa) {
print("sound blaster didnt respond #%.2x\n", i);
return;
}
sbcmd(0xe1); /* get version */
audio.major = sbread();
audio.minor = sbread();
if(audio.major != 4) {
print("bad soundblaster model #%.2x #.2x\n", audio.major, audio.minor);
return;
}
/*
* initialize the mixer
*/
mxcmd(0x00, 0); /* Reset mixer */
mxvolume();
/*
* set up irq/dma chans
*/
mxcmd(0x80, /* irq */
(Irq==2)? 1:
(Irq==5)? 2:
(Irq==7)? 4:
(Irq==10)? 8:
0);
mxcmd(0x81, 1<<Dma); /* dma */
}
Chan*
audioattach(char *param)
{
return devattach('A', param);
}
Chan*
audioclone(Chan *c, Chan *nc)
{
return devclone(c, nc);
}
int
audiowalk(Chan *c, char *name)
{
return devwalk(c, name, audiodir, NPORT, devgen);
}
void
audiostat(Chan *c, char *db)
{
devstat(c, db, audiodir, NPORT, devgen);
}
Chan*
audioopen(Chan *c, int omode)
{
if(audio.major != 4)
error(Emajor);
switch(c->qid.path & ~CHDIR) {
default:
error(Eperm);
break;
case Qvolume:
case Qdir:
break;
case Qaudio:
if(audio.bufinit == 0) {
audio.bufinit = 1;
sbbufinit();
}
audio.amode = Awrite;
if((omode&7) == OREAD)
audio.amode = Aread;
setempty();
audio.curcount = 0;
break;
}
c = devopen(c, omode, audiodir, NPORT, devgen);
c->mode = openmode(omode);
c->flag |= COPEN;
c->offset = 0;
return c;
}
void
audiocreate(Chan *c, char *name, int omode, ulong perm)
{
USED(c);
USED(name);
USED(omode);
USED(perm);
error(Eperm);
}
void
audioclose(Chan *c)
{
switch(c->qid.path & ~CHDIR) {
default:
error(Eperm);
break;
case Qdir:
case Qvolume:
break;
case Qaudio:
if(c->flag & COPEN) {
while(audio.active)
waitaudio();
setempty();
}
break;
}
}
long
audioread(Chan *c, char *a, long n, ulong offset)
{
long m, o, n0, bn;
char buf[256];
Buf *b;
int j;
n0 = n;
switch(c->qid.path & ~CHDIR) {
default:
error(Eperm);
break;
case Qdir:
return devdirread(c, a, n, audiodir, NPORT, devgen);
case Qaudio:
if(audio.amode != Aread)
error(Emode);
while(n > 0) {
b = audio.filling;
if(b == 0) {
b = getbuf(&audio.full);
if(b == 0) {
waitaudio();
continue;
}
audio.filling = b;
swab(b->virt);
audio.curcount = 0;
}
m = Bufsize-audio.curcount;
if(m > n)
m = n;
memmove(a, b->virt+audio.curcount, m);
audio.curcount += m;
n -= m;
a += m;
if(audio.curcount >= Bufsize) {
audio.filling = 0;
putbuf(&audio.empty, b);
}
}
break;
case Qvolume:
j = 0;
for(m=0; volumes[m].name; m++) {
o = *volumes[m].ptr1;
if(volumes[m].flag & Fmono)
j += snprint(buf+j, sizeof(buf)-j, "%s %d\n", volumes[m].name, o);
else {
bn = *volumes[m].ptr2;
if(o == bn)
j += snprint(buf+j, sizeof(buf)-j, "%s both %d\n", volumes[m].name, o);
else
j += snprint(buf+j, sizeof(buf)-j, "%s left %d right %d\n",
volumes[m].name, o, bn);
}
}
return readstr(offset, a, n, buf);
}
return n0-n;
}
Block*
audiobread(Chan *c, long n, ulong offset)
{
return devbread(c, n, offset);
}
long
audiowrite(Chan *c, char *a, long n, ulong offset)
{
long m, n0;
int i, nf, v, left, right;
char buf[255], *field[Ncmd];
Buf *b;
USED(offset);
n0 = n;
switch(c->qid.path & ~CHDIR) {
default:
error(Eperm);
break;
case Qvolume:
v = 0;
left = 1;
right = 1;
if(n > sizeof(buf)-1)
n = sizeof(buf)-1;
memmove(buf, a, n);
buf[n] = '\0';
nf = getfields(buf, field, Ncmd, " \t\n");
for(i = 0; i < nf; i++){
/*
* a number is volume
*/
if(field[i][0] >= '0' && field[i][0] <= '9') {
m = strtoul(field[i], 0, 10);
if(left)
*volumes[v].ptr1 = m;
if(right)
*volumes[v].ptr2 = m;
mxvolume();
goto cont0;
}
for(m=0; volumes[m].name; m++) {
if(strcmp(field[i], volumes[m].name) == 0) {
v = m;
goto cont0;
}
}
if(strcmp(field[i], "reset") == 0) {
resetlevel();
mxvolume();
goto cont0;
}
if(strcmp(field[i], "left") == 0) {
left = 1;
right = 0;
goto cont0;
}
if(strcmp(field[i], "right") == 0) {
left = 0;
right = 1;
goto cont0;
}
if(strcmp(field[i], "both") == 0) {
left = 1;
right = 1;
goto cont0;
}
error(Evolume);
break;
cont0:;
}
break;
case Qaudio:
if(audio.amode != Awrite)
error(Emode);
while(n > 0) {
b = audio.filling;
if(b == 0) {
b = getbuf(&audio.empty);
if(b == 0) {
waitaudio();
continue;
}
audio.filling = b;
audio.curcount = 0;
}
m = Bufsize-audio.curcount;
if(m > n)
m = n;
memmove(b->virt+audio.curcount, a, m);
audio.curcount += m;
n -= m;
a += m;
if(audio.curcount >= Bufsize) {
audio.filling = 0;
swab(b->virt);
putbuf(&audio.full, b);
}
}
break;
}
return n0 - n;
}
long
audiobwrite(Chan *c, Block *bp, ulong offset)
{
return devbwrite(c, bp, offset);
}
void
audioremove(Chan *c)
{
USED(c);
error(Eperm);
}
void
audiowstat(Chan *c, char *dp)
{
USED(c);
USED(dp);
error(Eperm);
}
static void
swab(uchar *a)
{
ulong *p, *ep, b;
p = (ulong*)a;
ep = p + (Bufsize>>2);
while(p < ep) {
b = *p;
b = (b>>24) | (b<<24) |
((b&0xff0000) >> 8) |
((b&0x00ff00) << 8);
*p++ = b;
}
}
.
## diffname port/devaudio.c 1995/0214
## diff -e /n/fornaxdump/1995/0119/sys/src/brazil/port/devaudio.c /n/fornaxdump/1995/0214/sys/src/brazil/port/devaudio.c
831a
if(!SBswab)
return;
.
798a
poperror();
qunlock(&audio);
.
772a
qlock(&audio);
if(waserror()){
qunlock(&audio);
nexterror();
}
.
667a
poperror();
qunlock(&audio);
.
642a
qlock(&audio);
if(waserror()){
qunlock(&audio);
nexterror();
}
.
617a
poperror();
qunlock(&audio);
.
614a
qlock(&audio);
audio.amode = Aclosed;
if(waserror()){
qunlock(&audio);
nexterror();
}
.
578a
qunlock(&audio);
.
572,576c
audio.amode = amode;
.
567a
amode = Awrite;
if((omode&7) == OREAD)
amode = Aread;
qlock(&audio);
if(audio.amode != Aclosed){
qunlock(&audio);
error(Einuse);
}
.
553a
int amode;
.
519,522c
(sbconf.irq==2)? 1:
(sbconf.irq==5)? 2:
(sbconf.irq==7)? 4:
(sbconf.irq==10)? 8:
.
492c
outb(blaster.reset, 0);
.
490c
outb(blaster.reset, 1);
.
487a
audio.amode = Aclosed;
.
486a
setvec(Int0vec+sbconf.irq, pcaudiosbintr, 0);
.
485a
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;
.
483a
ISAConf sbconf;
.
462a
iunlock(&blaster);
.
454a
ilock(&blaster);
.
430c
print("audio timeout\n"); /**/
.
405a
pcaudiosbintr(Ureg *ureg, void *rock)
{
USED(ureg, rock);
/* print("sb16 audio interrupt\n"); /**/
audiosbintr();
}
void
.
399c
dummy = inb(blaster.clri401);
.
396c
dummy = inb(blaster.clri8);
.
391a
iunlock(&blaster);
.
390c
ilock(&blaster);
dummy = inb(blaster.clri16);
.
378d
373,375d
363a
iunlock(&blaster);
.
349d
346,347c
else
.
342,344c
ilock(&blaster);
dmaend(Dma);
if(audio.amode == Aread)
.
326c
dmaend(Dma);
.
309,322c
dmasetup(Dma, b->virt, Bufsize, audio.amode == Aread);
.
290d
252c
iunlock(&blaster);
.
217,219c
ilock(&blaster);
.
175,176c
outb(blaster.mixaddr, addr);
s = inb(blaster.mixdata);
.
165,166c
outb(blaster.mixaddr, addr);
outb(blaster.mixdata, val);
.
154c
return inb(blaster.read);
.
152c
s = inb(blaster.rstatus);
.
138c
outb(blaster.write, val);
.
136c
s = inb(blaster.wstatus);
.
126c
static char Emajor[] = "SoundBlaster version too old";
.
123a
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;
.
75c
int amode; /* Aclosed/Aread/Awrite for /audio */
.
69a
QLock;
.
29c
Aclosed = 0,
Aread,
.
14,15d
## diffname port/devaudio.c 1995/0215
## diff -e /n/fornaxdump/1995/0214/sys/src/brazil/port/devaudio.c /n/fornaxdump/1995/0215/sys/src/brazil/port/devaudio.c
84d
## diffname port/devaudio.c 1995/0216
## diff -e /n/fornaxdump/1995/0215/sys/src/brazil/port/devaudio.c /n/fornaxdump/1995/0216/sys/src/brazil/port/devaudio.c
433c
/* print("audio timeout\n"); /**/
.
## diffname port/devaudio.c 1995/0217
## diff -e /n/fornaxdump/1995/0216/sys/src/brazil/port/devaudio.c /n/fornaxdump/1995/0217/sys/src/brazil/port/devaudio.c
282c
putbuf(AQueue *q, Buf *b)
.
268c
getbuf(AQueue *q)
.
86,87c
AQueue empty;
AQueue full;
.
61c
struct AQueue
.
15a
typedef struct AQueue AQueue;
.
## diffname port/devaudio.c 1995/0221
## diff -e /n/fornaxdump/1995/0217/sys/src/brazil/port/devaudio.c /n/fornaxdump/1995/0221/sys/src/brazil/port/devaudio.c
824,828d
816a
if(strcmp(field[i], "in") == 0) {
in = 1;
out = 0;
goto cont0;
}
if(strcmp(field[i], "out") == 0) {
in = 0;
out = 1;
goto cont0;
}
.
807a
in = 1;
out = 1;
left = 1;
right = 1;
.
797,800c
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;
.
784a
in = 1;
out = 1;
.
782c
v = Vaudio;
.
769c
int i, nf, v, left, right, in, out;
.
751a
j += snprint(buf+j, sizeof(buf)-j, "\n");
.
740,750c
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);
}
.
687,688c
int liv, riv, lov, rov;
long m, n0;
char buf[300];
.
631a
mxvolume();
.
482,483c
audio.lovol[i] = volumes[i].ilval;
audio.rovol[i] = volumes[i].irval;
audio.livol[i] = volumes[i].ilval;
audio.rivol[i] = volumes[i].irval;
.
347,348c
speed = audio.lovol[Vspeed];
}
sbcmd(speed>>8);
sbcmd(speed);
.
345c
speed = audio.livol[Vspeed];
} else {
.
343c
if(audio.amode == Aread) {
.
339a
int speed;
.
262,264c
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 */
.
259,260c
mxcmdu(0x46, left[Vbass]);
mxcmdu(0x47, right[Vbass]);
.
256,257c
mxcmdu(0x44, left[Vtreb]);
mxcmdu(0x45, right[Vtreb]);
.
251,254c
mxcmds(0x3a, left[Vmic]);
mxcmds(0x3b, left[Vspeaker]);
.
248,249c
mxcmds(0x38, left[Vline]);
mxcmds(0x39, right[Vline]);
.
245,246c
mxcmds(0x36, left[Vcd]);
mxcmds(0x37, right[Vcd]);
.
242,243c
mxcmds(0x34, left[Vsynth]);
mxcmds(0x35, right[Vsynth]);
.
239,240c
mxcmds(0x32, left[Vaudio]);
mxcmds(0x33, right[Vaudio]);
.
236,237c
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 */
.
233,234d
231a
int *left, *right;
int source;
if(audio.amode == Aread){
left = audio.livol;
right = audio.rivol;
}else{
left = audio.lovol;
right = audio.rovol;
}
.
110,120c
[Vspeed] "speed", Fin|Fout|Fmono, Speed, Speed,
.
107,108c
[Vtreb] "treb", Fout, 50, 50,
[Vbass] "bass", Fout, 50, 50,
.
103,105c
[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,
.
99c
int ilval; /* initial values */
.
96,97d
77,82c
int rivol[Nvol]; /* right/left input/output volumes */
int livol[Nvol];
int rovol[Nvol];
int lovol[Nvol];
.
43,55d
31a
Vaudio = 0,
Vsynth,
Vcd,
Vline,
Vmic,
Vspeaker,
Vtreb,
Vbass,
Vspeed,
Nvol,
.
26a
Fin = 2,
Fout = 4,
.
18d
## diffname port/devaudio.c 1995/0804
## diff -e /n/fornaxdump/1995/0221/sys/src/brazil/port/devaudio.c /n/fornaxdump/1995/0804/sys/src/brazil/port/devaudio.c
954,956d
952c
audiowstat(Chan*, char*)
.
946,947d
944c
audioremove(Chan*)
.
816,817d
809c
audiowrite(Chan *c, char *a, long n, ulong)
.
669,673d
667c
audiocreate(Chan*, char*, int, ulong)
.
439d
437c
anybuf(void*)
.
425d
423c
pcaudiosbintr(Ureg*, void*)
.
## diffname port/devaudio.c 1996/0223
## diff -e /n/fornaxdump/1995/0804/sys/src/brazil/port/devaudio.c /n/fornaxdump/1996/0223/sys/src/brazil/port/devaudio.c
10d
## diffname port/devaudio.c 1996/0315
## diff -e /n/fornaxdump/1996/0223/sys/src/brazil/port/devaudio.c /n/fornaxdump/1996/0315/sys/src/brazil/port/devaudio.c
825c
nf = parsefields(buf, field, Ncmd, " \t\n");
.
## diffname port/devaudio.c 1996/1024
## diff -e /n/fornaxdump/1996/0315/sys/src/brazil/port/devaudio.c /n/fornaxdump/1996/1024/sys/src/brazil/port/devaudio.c
591c
mxcmd(0x81, 1<<blaster.dma); /* dma */
.
573c
print("bad soundblaster model #%.2x #%.2x; not SB 16\n", audio.major, audio.minor);
.
551c
seteisadma(blaster.dma, audiodmaintr);
.
539a
blaster.dma = sbconf.dma;
.
536c
print("devaudio: bad sb16 irq %d\n", sbconf.irq);
.
526c
print("devaudio: bad sb16 port 0x%x\n", sbconf.port);
.
513a
sbconf.dma = 5;
.
359c
dmaend(blaster.dma);
.
341c
dmaend(blaster.dma);
.
337c
dmasetup(blaster.dma, b->virt, Bufsize, audio.amode == Aread);
.
128c
static char Emajor[] = "soundblaster not responding/wrong version";
.
123a
int dma;
.
## diffname port/devaudio.c 1996/1025
## diff -e /n/fornaxdump/1996/1024/sys/src/brazil/port/devaudio.c /n/fornaxdump/1996/1025/sys/src/brazil/port/devaudio.c
515c
sbconf.dma = Dma;
.
## diffname port/devaudio.c 1997/0327
## diff -e /n/fornaxdump/1996/1025/sys/src/brazil/port/devaudio.c /n/emeliedump/1997/0327/sys/src/brazil/port/devaudio.c
965a
Dev audiodevtab = {
devreset,
audioinit,
audioattach,
devclone,
audiowalk,
audiostat,
audioopen,
devcreate,
audioclose,
audioread,
devbread,
audiowrite,
devbwrite,
devremove,
devwstat,
};
.
931,948d
798,804c
static long
.
720c
return devdirread(c, a, n, audiodir, nelem(audiodir), devgen);
.
704c
static long
.
667,673c
static void
.
659c
c = devopen(c, omode, audiodir, nelem(audiodir), devgen);
.
622c
static Chan*
.
619c
devstat(c, db, audiodir, nelem(audiodir), devgen);
.
616c
static void
.
613c
return devwalk(c, name, audiodir, nelem(audiodir), devgen);
.
604,610c
static int
.
598c
static Chan*
.
577c
print("#A: model #%.2x #%.2x; not SB 16\n", audio.major, audio.minor);
.
568c
print("#A: no response #%.2x\n", i);
.
553a
blaster.dma = sbconf.dma;
.
542,543d
538c
print("#A: bad irq %d\n", sbconf.irq);
.
528c
print("#A: bad port 0x%x\n", sbconf.port);
.
508c
static void
.
490,494d
453c
/* print("#A: audio timeout\n"); /**/
.
432c
/* print("#A: dma interrupt\n"); /**/
.
425c
/* print("#A: audio interrupt\n"); /**/
.
160c
/* print("#A: sbread did not respond\n"); /**/
.
145c
/* print("#A: sbcmd (#%.2x) timeout\n", val); /**/
.
107,108c
[Vspeed] "speed", Fin|Fout|Fmono, Speed, Speed,
0
.
97,100c
[Vaudio] "audio", Fout, 50, 50,
[Vsynth] "synth", Fin|Fout, 0, 0,
[Vcd] "cd", Fin|Fout, 0, 0,
[Vline] "line", Fin|Fout, 0, 0,
.
13,14d
## diffname port/devaudio.c 1997/0408
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/devaudio.c /n/emeliedump/1997/0408/sys/src/brazil/port/devaudio.c
923a
'A',
"audio",
.
## diffname port/devaudio.c 1998/0317
## diff -e /n/emeliedump/1997/0408/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0317/sys/src/brazil/port/devaudio.c
571a
.
569,570c
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;
.
546a
blaster.startdma = sb16startdma;
blaster.intr = sb16intr;
.
512c
if(cistrcmp(sbconf.type, "sb16") != 0 && cistrcmp(sbconf.type, "ess1688") != 0)
.
500a
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;
}
.
423,424c
/*
* x86 interrupt interface.
*/
blaster.intr();
.
420a
audiosbintr(void)
{
/*
* Carrera interrupt interface.
*/
blaster.intr();
}
static void
.
419a
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");
}
.
394,395c
static void
sb16intr(void)
.
391c
blaster.startdma();
.
382a
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);
}
.
352c
sb16startdma(void)
.
336,337c
if(dmasetup(blaster.dma, b->virt, Bufsize, audio.amode == Aread) >= 0)
return;
print("#A: dmasetup fail\n");
putbuf(&audio.empty, b);
.
328c
if(b) /* shouldn't happen */
.
324c
if(b) /* shouldn't happen */
.
161a
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();
}
.
159c
return -1;
.
143c
/* print("#A: sbcmd (0x%.2x) timeout\n", val); /**/
.
122a
void (*startdma)(void);
void (*intr)(void);
.
## diffname port/devaudio.c 1998/0319
## diff -e /n/emeliedump/1998/0317/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0319/sys/src/brazil/port/devaudio.c
992c
audiowrite(Chan *c, char *a, long n, vlong)
.
904a
ulong offset = off;
.
898c
audioread(Chan *c, char *a, long n, vlong off)
.
## diffname port/devaudio.c 1998/0327
## diff -e /n/emeliedump/1998/0319/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0327/sys/src/brazil/port/devaudio.c
980c
j += snprint(buf+j, sizeof(buf)-j,
" out left %d right %d",
.
977c
j += snprint(buf+j, sizeof(buf)-j,
" in left %d right %d",
.
972,973c
if((volumes[m].flag&(Fin|Fout))==(Fin|Fout) &&
liv==lov && riv==rov)
j += snprint(buf+j, sizeof(buf)-j,
" left %d right %d",
.
969c
j += snprint(buf+j, sizeof(buf)-j,
" out %d", lov);
.
967c
j += snprint(buf+j, sizeof(buf)-j,
" in %d", liv);
.
## diffname port/devaudio.c 1998/0331
## diff -e /n/emeliedump/1998/0327/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0331/sys/src/brazil/port/devaudio.c
971c
" out %d", lov);
.
968c
" in %d", liv);
.
## diffname port/devaudio.c 1998/0512
## diff -e /n/emeliedump/1998/0331/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0512/sys/src/brazil/port/devaudio.c
784c
.
## diffname port/devaudio.c 1998/0603
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0603/sys/src/brazil/port/devaudio.c
881a
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();
}
.
## diffname port/devaudio.c 1998/0624
## diff -e /n/emeliedump/1998/0603/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0624/sys/src/brazil/port/devaudio.c
891c
if(!audio.active && audio.full.first)
.
884,885c
b = audio.filling;
if(b) {
.
882c
if(audio.amode == Awrite) {
.
868a
Buf *b;
.
## diffname port/devaudio.c 1998/0825
## diff -e /n/emeliedump/1998/0624/sys/src/brazil/port/devaudio.c /n/emeliedump/1998/0825/sys/src/brazil/port/devaudio.c
736c
print("#A: bad irq %lud\n", sbconf.irq);
.
726c
print("#A: bad port 0x%lux\n", sbconf.port);
.
693c
print("#A: bad ESS1688 dma %lud\n", sbconf->dma);
.
677c
print("#A: bad ESS1688 irq %lud\n", sbconf->irq);
.
## diffname port/devaudio.c 1999/0219
## diff -e /n/emeliedump/1998/0825/sys/src/brazil/port/devaudio.c /n/emeliedump/1999/0219/sys/src/brazil/port/devaudio.c
888c
memset(b->virt+audio.curcount, 0, Bufsize-audio.curcount);
.
## diffname port/devaudio.c 1999/0320
## diff -e /n/emeliedump/1999/0219/sys/src/brazil/port/devaudio.c /n/emeliedump/1999/0320/sys/src/brazil/port/devaudio.c
1018a
a = vp;
.
1017a
char *a;
.
1012c
audiowrite(Chan *c, void *vp, long n, vlong)
.
920a
a = v;
.
918a
char *a;
.
911c
audioread(Chan *c, void *v, long n, vlong off)
.
## diffname port/devaudio.c 1999/0504
## diff -e /n/emeliedump/1999/0320/sys/src/brazil/port/devaudio.c /n/emeliedump/1999/0504/sys/src/brazil/port/devaudio.c
714c
sbconf.irq = IrqAUDIO;
.
## diffname port/devaudio.c 1999/1005
## diff -e /n/emeliedump/1999/0504/sys/src/brazil/port/devaudio.c /n/emeliedump/1999/1005/sys/src/brazil/port/devaudio.c
1007d
967a
case Qstatus:
buf[0] = 0;
snprint(buf, sizeof(buf), "bytes %lud\ntime %lld\n",
audio.totcount, audio.tottime);
return readstr(offset, a, n, buf);
.
877a
case Qstatus:
.
833a
case Qstatus:
if((omode&7) != OREAD)
error(Eperm);
.
800a
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);
.
792c
* 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.
.
755,757d
710c
int i, x;
static int irq[] = {2,5,7,10};
.
627a
audio.totcount = 0;
audio.tottime = 0LL;
.
540a
audio.totcount += Bufsize;
audio.tottime = todget(nil);
.
518a
audio.totcount += Bufsize;
audio.tottime = todget(nil);
.
492a
audio.tottime = todget(nil);
.
401a
audio.tottime = todget(nil);
.
78a
ulong totcount; /* how many bytes processed since open */
vlong tottime; /* time at which totcount bytes were processed */
.
49a
"audiostat",{Qstatus}, 0, 0444,
.
20a
Qstatus,
.
## diffname port/devaudio.c 1999/1015
## diff -e /n/emeliedump/1999/1005/sys/src/brazil/port/devaudio.c /n/emeliedump/1999/1015/sys/src/brazil/port/devaudio.c
745a
case 9:
.
## diffname port/devaudio.c 1999/1122
## diff -e /n/emeliedump/1999/1015/sys/src/brazil/port/devaudio.c /n/emeliedump/1999/1122/sys/src/9/port/devaudio.c
814a
(sbconf.irq==9)? 1:
.
## diffname port/devaudio.c 2000/0308
## diff -e /n/emeliedump/1999/1122/sys/src/9/port/devaudio.c /n/emeliedump/2000/0308/sys/src/9/port/devaudio.c
1084c
nf = getfields(buf, field, Ncmd, 1, " \t\n");
.
## diffname port/devaudio.c 2000/0407
## diff -e /n/emeliedump/2000/0308/sys/src/9/port/devaudio.c /n/emeliedump/2000/0407/sys/src/9/port/devaudio.c
1192a
}
.
1191c
if(!SBswab){
USED(a);
.
## diffname port/devaudio.c 2001/0503
## diff -e /n/emeliedump/2000/0407/sys/src/9/port/devaudio.c /n/emeliedump/2001/0503/sys/src/9/port/devaudio.c
935,938c
while(waserror())
;
.
911c
error(Eperm); /* can't happen */
.
## diffname port/devaudio.c 2001/0526
## diff -e /n/emeliedump/2001/0503/sys/src/9/port/devaudio.c /n/emeliedump/2001/0526/sys/src/9/port/devaudio.c
192a
delay(1);
.
191a
delay(1);
.
146a
delay(1);
.
## diffname port/devaudio.c 2001/0527
## diff -e /n/emeliedump/2001/0526/sys/src/9/port/devaudio.c /n/emeliedump/2001/0527/sys/src/9/port/devaudio.c
1214d
1069c
switch((ulong)c->qid.path) {
.
963c
switch((ulong)c->qid.path) {
.
938,939c
if(waserror()){
qunlock(&audio);
nexterror();
}
.
914c
error(Eperm);
.
912c
switch((ulong)c->qid.path) {
.
867c
switch((ulong)c->qid.path) {
.
856c
return devstat(c, db, n, audiodir, nelem(audiodir), devgen);
.
853,854c
static int
audiostat(Chan *c, uchar *db, int n)
.
850c
return devwalk(c, nc, name, nname, audiodir, nelem(audiodir), devgen);
.
847,848c
static Walkqid*
audiowalk(Chan *c, Chan *nc, char **name, int nname)
.
195d
193d
147d
48a
".", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
.
## diffname port/devaudio.c 2001/1013
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/devaudio.c /n/emeliedump/2001/1013/sys/src/9/port/devaudio.c
1173a
audio.buffered += m;
.
998a
audio.buffered -= m;
.
928a
audio.buffered += Bufsize-audio.curcount;
.
853a
audiodir[Qaudio].length = audio.buffered;
.
636a
audio.buffered = 0;
.
355a
audio.buffered -= Bufsize;
}
.
354c
if(b){
.
351a
audio.buffered += Bufsize;
}
.
350c
if(b){
.
103,104c
[Vline] "line", Fin|Fout, 0, 0,
[Vmic] "mic", Fin|Fout|Fmono, 0, 0,
.
100,101c
[Vaudio] "audio", Fout, 50, 50,
[Vsynth] "synth", Fin|Fout, 0, 0,
.
85c
Buf buf[Nbuf]; /* buffers and queues */
.
83a
int buffered; /* number of bytes en route */
.
76c
int rivol[Nvol]; /* right/left input/output volumes */
.
74c
int intr; /* boolean an interrupt has happened */
.
71,72c
int bufinit; /* boolean if buffers allocated */
int curcount; /* how much data in current buffer */
.
## diffname port/devaudio.c 2001/1016
## diff -e /n/emeliedump/2001/1013/sys/src/9/port/devaudio.c /n/emeliedump/2001/1016/sys/src/9/port/devaudio.c
1019,1020c
snprint(buf, sizeof(buf), "bufsize %6d buffered %6d offset %10lud time %19lld\n",
Bufsize, audio.buffered, audio.totcount, audio.tottime);
.
## diffname port/devaudio.c 2001/1017
## diff -e /n/emeliedump/2001/1016/sys/src/9/port/devaudio.c /n/emeliedump/2001/1017/sys/src/9/port/devaudio.c
1020c
Bufsize, audio.buffered, audio.totcount<0?0:audio.totcount, audio.tottime);
.
898a
if (amode == Aread)
audio.totcount -= Bufsize;
.
504d
412d
## diffname port/devaudio.c 2001/1018
## diff -e /n/emeliedump/2001/1017/sys/src/9/port/devaudio.c /n/emeliedump/2001/1018/sys/src/9/port/devaudio.c
1020c
Bufsize, audio.buffered, audio.totcount, audio.tottime);
.
897,898d
## diffname port/devaudio.c 2001/1019
## diff -e /n/emeliedump/2001/1018/sys/src/9/port/devaudio.c /n/emeliedump/2001/1019/sys/src/9/port/devaudio.c
624a
p += Bufsize;
.
621d
619a
p = (uchar*)(((ulong)xalloc((Nbuf+1) * Bufsize) + Bufsize-1)&~(Bufsize-1));
.
618c
uchar *p;
.
553,554d
529,530d
349a
if (b){
audio.totcount += Bufsize;
audio.tottime = todget(nil);
}
.
84d
70a
int buffered; /* number of bytes en route */
.
## diffname port/devaudio.c 2001/1117
## diff -e /n/emeliedump/2001/1019/sys/src/9/port/devaudio.c /n/emeliedump/2001/1117/sys/src/9/port/devaudio.c
1093c
nf = tokenize(buf, field, Ncmd);
.
## diffname port/devaudio.c 2001/1121
## diff -e /n/emeliedump/2001/1117/sys/src/9/port/devaudio.c /n/emeliedump/2001/1121/sys/src/9/port/devaudio.c
1151a
free(cb);
poperror();
.
1143c
if(strcmp(cb->f[i], "right") == 0) {
.
1138c
if(strcmp(cb->f[i], "left") == 0) {
.
1133c
if(strcmp(cb->f[i], "out") == 0) {
.
1128c
if(strcmp(cb->f[i], "in") == 0) {
.
1123c
if(strcmp(cb->f[i], "reset") == 0) {
.
1113c
if(strcmp(cb->f[i], volumes[m].name) == 0) {
.
1098,1099c
if(cb->f[i][0] >= '0' && cb->f[i][0] <= '9') {
m = strtoul(cb->f[i], 0, 10);
.
1093,1094c
for(i = 0; i < cb->nf; i++){
.
1088,1091c
cb = parsecmd(vp, n);
if(waserror()){
free(cb);
nexterror();
}
.
1070,1071c
int i, v, left, right, in, out;
Cmdbuf *cb;
.
## diffname port/devaudio.c 2002/0109
## diff -e /n/emeliedump/2001/1121/sys/src/9/port/devaudio.c /n/emeliedump/2002/0109/sys/src/9/port/devaudio.c
1223a
devshutdown,
.
## diffname port/devaudio.c 2002/0412
## diff -e /n/emeliedump/2002/0109/sys/src/9/port/devaudio.c /n/emeliedump/2002/0412/sys/src/9/port/devaudio.c
823a
.
796a
iofree(sbconf.port);
iofree(sbconf.port+0x100);
.
785a
iofree(sbconf.port);
iofree(sbconf.port+0x100);
.
756a
iofree(sbconf.port);
iofree(sbconf.port+0x100);
.
747a
if(ioalloc(sbconf.port, 0x10, 0, "audio") < 0){
print("#A: cannot ioalloc range %x+0x10\n", sbconf.port);
return;
}
if(ioalloc(sbconf.port+0x100, 1, 0, "audio.mpu401") < 0){
iofree(sbconf.port);
print("#A: cannot ioalloc range %x+0x01\n", sbconf.port+0x100);
return;
}
.
## diffname port/devaudio.c 2002/0414
## diff -e /n/emeliedump/2002/0412/sys/src/9/port/devaudio.c /n/emeliedump/2002/0414/sys/src/9/port/devaudio.c
755c
print("#A: cannot ioalloc range %lux+0x01\n", sbconf.port+0x100);
.
750c
print("#A: cannot ioalloc range %lux+0x10\n", sbconf.port);
.
## diffname port/devaudio.c 2002/0523
## diff -e /n/emeliedump/2002/0414/sys/src/9/port/devaudio.c /n/emeliedump/2002/0523/sys/src/9/port/devaudio.c
736c
if(sbconf.type == nil ||
(cistrcmp(sbconf.type, "sb16") != 0 &&
cistrcmp(sbconf.type, "ess1688") != 0))
.
## diffname port/devaudio.c 2003/0301
## diff -e /n/emeliedump/2002/0523/sys/src/9/port/devaudio.c /n/emeliedump/2003/0301/sys/src/9/port/devaudio.c
769c
print("#A: bad irq %d\n", sbconf.irq);
.
695c
print("#A: bad ESS1688 irq %d\n", sbconf->irq);
.
## diffname port/devaudio.c 2003/0406
## diff -e /n/emeliedump/2003/0301/sys/src/9/port/devaudio.c /n/emeliedump/2003/0406/sys/src/9/port/devaudio.c
350c
if(b){
.
|