Subject: port-amiga/1942: In order to load customized audio drivers hooks need be there
To: None <gnats-bugs@gnats.netbsd.org>
From: Niklas Hallqvist <niklas@filippa.appli.se>
List: netbsd-bugs
Date: 01/14/1996 17:56:12
>Number: 1942
>Category: port-amiga
>Synopsis: In order to load customized audio drivers hooks need be there
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: gnats-admin (GNATS administrator)
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Sun Jan 14 12:20:05 1996
>Last-Modified:
>Originator: Niklas Hallqvist
>Organization:
Applitron Datasystem AB
>Release: 951218
>Environment:
System: NetBSD filippa.appli.se 1.1_ALPHA NetBSD 1.1_ALPHA (FILIPPA) #562: Mon Dec 11 19:15:43 MET 1995 root@filippa.appli.se:/u3/newex/sys/arch/amiga/compile/FILIPPA amiga
>Description:
The standard custom chipset audio system can only feed a simple sample
n times to the audio device. There need to be hooks to change buffers
at interrupt time.
>How-To-Repeat:
Try to load Tim Newsham's audio LKM on a vanilla NetBSD kernel
>Fix:
Add hooks for custom audio players. This is the original untouched
kernel diffs from Tim Newsham <newsham@hookomo.aloha.net> found in his
well-known audio LKM kit.
*** old-NetBSD/src/sys/arch/amiga/amiga/cc.c
--- NetBSD/src/sys/arch/amiga/amiga/cc.c
***************
*** 323,334 ****
*/
struct audio_channel {
! u_short play_count;
};
/* - channel[4] */
/* the data for each audio channel and what to do with it. */
! static struct audio_channel channel[4];
/* audio vbl node for vbl function */
struct vbl_node audio_vbl_node;
--- 323,335 ----
*/
struct audio_channel {
! u_short play_count; /* number of times to loop sample */
! handler_func_t handler; /* interupt handler for channel */
};
/* - channel[4] */
/* the data for each audio channel and what to do with it. */
! struct audio_channel channel[4];
/* audio vbl node for vbl function */
struct vbl_node audio_vbl_node;
***************
*** 337,342 ****
--- 338,344 ----
cc_init_audio()
{
int i;
+ extern int defchannel_handler();
/*
* disable all audio interupts
***************
*** 346,353 ****
/*
* initialize audio channels to off.
*/
! for (i=0; i < 4; i++)
channel[i].play_count = 0;
}
--- 348,357 ----
/*
* initialize audio channels to off.
*/
! for (i=0; i < 4; i++) {
channel[i].play_count = 0;
+ channel[i].handler = defchannel_handler;
+ }
}
***************
*** 393,414 ****
if ((ir & (flag << 7)) == 0)
continue;
! if (channel[i].play_count)
! channel[i].play_count--;
! else {
! /*
! * disable DMA to this channel and
! * disable interrupts to this channel
! */
! custom.dmacon = flag;
! custom.intena = (flag << 7);
! }
/*
* clear this channels interrupt.
*/
custom.intreq = (flag << 7);
}
-
out:
/*
* enable audio interupts with dma still set.
--- 397,410 ----
if ((ir & (flag << 7)) == 0)
continue;
! if (channel[i].handler)
! channel[i].handler(i);
!
/*
* clear this channels interrupt.
*/
custom.intreq = (flag << 7);
}
out:
/*
* enable audio interupts with dma still set.
***************
*** 418,423 ****
--- 414,439 ----
custom.intena = INTF_SETCLR | (audio_dma << 7);
}
+ /*
+ * this is the channel handler used by the system
+ * other software modules are free to install their own
+ * handler
+ */
+ defchannel_handler(i)
+ int i;
+ {
+ if (channel[i].play_count)
+ channel[i].play_count--;
+ else {
+ /*
+ * disable DMA to this channel and
+ * disable interrupts to this channel
+ */
+ custom.dmacon = (1 << i);
+ custom.intena = (1 << (i + 7));
+ }
+ }
+
void
play_sample(len, data, period, volume, channels, count)
u_short len, *data, period, volume, channels;
***************
*** 430,442 ****
/* load the channels */
for (ch = 0; ch < 4; ch++) {
! if ((dmabits & (ch << ch)) == 0)
continue;
! custom.aud[ch].len = len;
! custom.aud[ch].lc = data;
custom.aud[ch].per = period;
custom.aud[ch].vol = volume;
! channel[ch].play_count = count;
}
/*
* turn on interrupts and enable dma for channels and
--- 446,461 ----
/* load the channels */
for (ch = 0; ch < 4; ch++) {
! if ((dmabits & (1 << ch)) == 0)
continue;
! /* busy */
! if (channel[ch].handler != defchannel_handler)
! continue;
! channel[ch].play_count = count;
custom.aud[ch].per = period;
custom.aud[ch].vol = volume;
! custom.aud[ch].len = len;
! custom.aud[ch].lc = data;
}
/*
* turn on interrupts and enable dma for channels and
*** old-NetBSD/src/sys/arch/amiga/amiga/cc.h
--- NetBSD/src/sys/arch/amiga/amiga/cc.h
***************
*** 147,152 ****
--- 147,154 ----
#define CHIPMEMTOP (0x00200000)
#define NCHIPMEMPG btoc(CHIPMEMTOP - CHIPMEMBASE)
+ typedef int (*handler_func_t)();
+
/*
* Prototypes.
*/
>Audit-Trail:
>Unformatted: