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: