sb16: new approach, works in qemu
This commit is contained in:
parent
e7e04b5cbb
commit
b74418c2ce
5 changed files with 533 additions and 607 deletions
File diff suppressed because it is too large
Load diff
|
@ -857,7 +857,7 @@ floppyxfer(FDrive *dp, int cmd, void *a, long off, long n)
|
|||
dmaend(DMAchan);
|
||||
nexterror();
|
||||
}
|
||||
dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread);
|
||||
dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread ? DMAREAD : DMAWRITE);
|
||||
if(dp->len < 0)
|
||||
error(Eio);
|
||||
|
||||
|
@ -999,7 +999,7 @@ floppyformat(FDrive *dp, Cmdbuf *cb)
|
|||
dmaend(DMAchan);
|
||||
nexterror();
|
||||
}
|
||||
if(dmasetup(DMAchan, buf, bp-buf, 0) < 0)
|
||||
if(dmasetup(DMAchan, buf, bp-buf, DMAWRITE) < 0)
|
||||
error(Eio);
|
||||
|
||||
/*
|
||||
|
|
|
@ -18,7 +18,7 @@ struct DMAxfer
|
|||
int blen; /* bounce buffer length */
|
||||
void* va; /* virtual address destination/src */
|
||||
long len; /* bytes to be transferred */
|
||||
int isread;
|
||||
int flags;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -81,7 +81,7 @@ _i8237alloc(void)
|
|||
if(i8237dma > 2)
|
||||
i8237dma = 2;
|
||||
|
||||
bva = xspanalloc(64*1024*i8237dma, BY2PG, 64*1024);
|
||||
bva = xspanalloc(64*1024*i8237dma, 0, 64*1024);
|
||||
if(bva == nil || PADDR(bva)+64*1024*i8237dma > 16*MB){
|
||||
/*
|
||||
* This will panic with the current
|
||||
|
@ -137,11 +137,38 @@ dmainit(int chan, int maxtransfer)
|
|||
xp->bpa = PADDR(xp->bva);
|
||||
xp->blen = maxtransfer;
|
||||
xp->len = 0;
|
||||
xp->isread = 0;
|
||||
xp->flags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void*
|
||||
dmabva(int chan)
|
||||
{
|
||||
DMA *dp;
|
||||
DMAxfer *xp;
|
||||
|
||||
dp = &dma[(chan>>2)&1];
|
||||
chan = chan & 3;
|
||||
xp = &dp->x[chan];
|
||||
return xp->bva;
|
||||
}
|
||||
|
||||
int
|
||||
dmacount(int chan)
|
||||
{
|
||||
int retval;
|
||||
DMA *dp;
|
||||
|
||||
dp = &dma[(chan>>2)&1];
|
||||
chan = chan & 3;
|
||||
ilock(dp);
|
||||
retval = inb(dp->count[chan]);
|
||||
retval |= inb(dp->count[chan]) << 8;
|
||||
iunlock(dp);
|
||||
return ((retval<<dp->shift)+1) & 0xFFFF;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup a dma transfer. if the destination is not in kernel
|
||||
* memory, allocate a page for the transfer.
|
||||
|
@ -153,7 +180,7 @@ dmainit(int chan, int maxtransfer)
|
|||
* boundaries)
|
||||
*/
|
||||
long
|
||||
dmasetup(int chan, void *va, long len, int isread)
|
||||
dmasetup(int chan, void *va, long len, int flags)
|
||||
{
|
||||
DMA *dp;
|
||||
ulong pa;
|
||||
|
@ -175,11 +202,11 @@ dmasetup(int chan, void *va, long len, int isread)
|
|||
return -1;
|
||||
if(len > xp->blen)
|
||||
len = xp->blen;
|
||||
if(!isread)
|
||||
if(!(flags & DMAREAD))
|
||||
memmove(xp->bva, va, len);
|
||||
xp->va = va;
|
||||
xp->len = len;
|
||||
xp->isread = isread;
|
||||
xp->flags = flags;
|
||||
pa = xp->bpa;
|
||||
}
|
||||
else
|
||||
|
@ -189,7 +216,7 @@ dmasetup(int chan, void *va, long len, int isread)
|
|||
* this setup must be atomic
|
||||
*/
|
||||
ilock(dp);
|
||||
mode = (isread ? 0x44 : 0x48) | chan;
|
||||
mode = ((flags & DMAREAD) ? 0x44 : 0x48) | ((flags & DMALOOP) ? 0x10 : 0) | chan;
|
||||
outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */
|
||||
outb(dp->page[chan], pa>>16);
|
||||
outb(dp->cbp, 0); /* set count & address to their first byte */
|
||||
|
@ -238,7 +265,7 @@ dmaend(int chan)
|
|||
iunlock(dp);
|
||||
|
||||
xp = &dp->x[chan];
|
||||
if(xp->len == 0 || !xp->isread)
|
||||
if(xp->len == 0 || !(xp->flags & DMAREAD))
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -248,17 +275,3 @@ dmaend(int chan)
|
|||
xp->len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
int
|
||||
dmacount(int chan)
|
||||
{
|
||||
int retval;
|
||||
DMA *dp;
|
||||
|
||||
dp = &dma[(chan>>2)&1];
|
||||
outb(dp->cbp, 0);
|
||||
retval = inb(dp->count[chan]);
|
||||
retval |= inb(dp->count[chan]) << 8;
|
||||
return((retval<<dp->shift)+1);
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -18,10 +18,14 @@ int cpuidentify(void);
|
|||
void cpuidprint(void);
|
||||
void (*cycles)(uvlong*);
|
||||
void delay(int);
|
||||
void* dmabva(int);
|
||||
int dmacount(int);
|
||||
int dmadone(int);
|
||||
void dmaend(int);
|
||||
int dmainit(int, int);
|
||||
#define DMAWRITE 0
|
||||
#define DMAREAD 1
|
||||
#define DMALOOP 2
|
||||
long dmasetup(int, void*, long, int);
|
||||
#define evenaddr(x) /* x86 doesn't care */
|
||||
void fpclear(void);
|
||||
|
@ -181,5 +185,3 @@ int xchgw(ushort*, int);
|
|||
#define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1]))
|
||||
#define KADDR(a) kaddr(a)
|
||||
#define PADDR(a) paddr((void*)(a))
|
||||
|
||||
#define dcflush(a, b)
|
||||
|
|
|
@ -18,6 +18,7 @@ enum {
|
|||
Qaudioctl,
|
||||
Qaudiostatus,
|
||||
Qvolume,
|
||||
|
||||
Maxaudioprobes = 8,
|
||||
};
|
||||
|
||||
|
@ -48,19 +49,26 @@ audioreset(void)
|
|||
int i, ctlrno = 0;
|
||||
Audio **pp;
|
||||
Audioprobe *probe;
|
||||
|
||||
pp = &audiodevs;
|
||||
*pp = malloc(sizeof(Audio));
|
||||
(*pp)->ctlrno = ctlrno++;
|
||||
for(i = 0; i < naudioprobes; i++){
|
||||
|
||||
for(i=0; i<naudioprobes; i++){
|
||||
probe = &audioprobes[i];
|
||||
(*pp)->name = probe->name;
|
||||
while(!probe->probe(*pp)){
|
||||
|
||||
for(;;){
|
||||
memset(*pp, 0, sizeof(Audio));
|
||||
(*pp)->ctlrno = ctlrno;
|
||||
(*pp)->name = probe->name;
|
||||
if(probe->probe(*pp))
|
||||
break;
|
||||
|
||||
ctlrno++;
|
||||
pp = &(*pp)->next;
|
||||
*pp = malloc(sizeof(Audio));
|
||||
(*pp)->ctlrno = ctlrno++;
|
||||
(*pp)->name = probe->name;
|
||||
}
|
||||
}
|
||||
|
||||
free(*pp);
|
||||
*pp = nil;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue