*/
struct audio_channel {
- u_short play_count;
+ 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. */
-static struct audio_channel channel[4];
+struct audio_channel channel[4];
/* audio vbl node for vbl function */
struct vbl_node audio_vbl_node;
cc_init_audio()
{
int i;
+ extern int defchannel_handler();
/*
* disable all audio interupts
/*
* initialize audio channels to off.
*/
- for (i=0; i < 4; i++)
+ for (i=0; i < 4; i++) {
channel[i].play_count = 0;
+ channel[i].handler = defchannel_handler;
+ }
}
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);
- }
+ if (channel[i].handler)
+ channel[i].handler(i);
+
/*
* clear this channels interrupt.
*/
custom.intreq = (flag << 7);
}
-
out:
/*
* enable audio interupts with dma still set.
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;
/* load the channels */
for (ch = 0; ch < 4; ch++) {
- if ((dmabits & (ch << ch)) == 0)
+ if ((dmabits & (1 << ch)) == 0)
continue;
- custom.aud[ch].len = len;
- custom.aud[ch].lc = data;
+ /* busy */
+ if (channel[ch].handler != defchannel_handler)
+ continue;
+ channel[ch].play_count = count;
custom.aud[ch].per = period;
custom.aud[ch].vol = volume;
- channel[ch].play_count = count;
+ custom.aud[ch].len = len;
+ custom.aud[ch].lc = data;
}
/*
* turn on interrupts and enable dma for channels and