Subject: New console bell patch
To: port-mac68k Mailing List <port-mac68k@NetBSD.ORG>
From: Colin Wood <cwood@ichips.intel.com>
List: port-mac68k
Date: 05/08/1998 22:28:27
Attached below is a patch to the asc and ite drivers to use a new beep
routine for the console bell.  This routine is pretty much the same as
that used by my beep program, so if it worked for you, this patch should
work pretty much the same.  What this means is that anyone whose machine
uses an EASC should be able to hear a terminal bell with this patch
applied :-)

I've added some defines to ite.c that should allow you to define the
console bell's frequency, duration, and volume if you don't like the
defaults (880, 7, 100).  Just define:

options 	BELL_FREQ=880
options 	BELL_LENGTH=7
options 	BELL_VOLUME=100

in your kernel config file to change these values.  Please let me know if
I've managed to screw something up if you try this and it doesn't work.

Anyway, this diff is against 1.3 sources (should be the same as 1.3.1).
It might apply to -current if you separate out the ite.c patch from the
rest.  If you try this patch, please let me know how it goes.

Enjoy!

-- 
Colin Wood                                 cwood@ichips.intel.com
Component Design Engineer - PMD                 Intel Corporation
-----------------------------------------------------------------
I speak only on my own behalf, not for my employer.



Index: asc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/asc.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 asc.c
*** asc.c	1998/02/08 21:36:01	1.1.1.1
--- asc.c	1998/05/09 05:12:23
***************
*** 86,95 ****
  #define	MAC68K_IIFX_ASC_BASE	0x50f10000
  #define	MAC68K_ASC_LEN		0x01000
  
! static u_int8_t		asc_wave_tab[0x800];
! 
! static int	asc_ring_bell __P((void *, int, int, int));
! static void	asc_stop_bell __P((void *));
  
  static int	ascmatch __P((struct device *, struct cfdata *, void *));
  static void	ascattach __P((struct device *, struct device *, void *));
--- 86,93 ----
  #define	MAC68K_IIFX_ASC_BASE	0x50f10000
  #define	MAC68K_ASC_LEN		0x01000
  
! static int	asc_start_bell __P((void *, int, int, int));
! static void	asc_ring_bell __P((void *));
  
  static int	ascmatch __P((struct device *, struct cfdata *, void *));
  static void	ascattach __P((struct device *, struct device *, void *));
***************
*** 141,147 ****
  	struct asc_softc *sc = (struct asc_softc *)self;
  	struct obio_attach_args *oa = (struct obio_attach_args *)aux;
  	bus_addr_t addr;
- 	int i;
  
  	sc->sc_tag = oa->oa_tag;
  	if (oa->oa_addr != (-1))
--- 139,144 ----
***************
*** 156,182 ****
  		return;
  	}
  	sc->sc_open = 0;
! 	sc->sc_ringing = 0;
  
- 	for (i = 0; i < 256; i++) {	/* up part of wave, four voices? */
- 		asc_wave_tab[i] = i / 4;
- 		asc_wave_tab[i + 512] = i / 4;
- 		asc_wave_tab[i + 1024] = i / 4;
- 		asc_wave_tab[i + 1536] = i / 4;
- 	}
- 	for (i = 0; i < 256; i++) {	/* down part of wave, four voices? */
- 		asc_wave_tab[i + 256] = 0x3f - (i / 4);
- 		asc_wave_tab[i + 768] = 0x3f - (i / 4);
- 		asc_wave_tab[i + 1280] = 0x3f - (i / 4);
- 		asc_wave_tab[i + 1792] = 0x3f - (i / 4);
- 	}
  
! 	printf(": Apple Sound Chip");
  	if (oa->oa_addr != (-1))
  		printf(" at %x", oa->oa_addr);
  	printf("\n");
  
! 	mac68k_set_bell_callback(asc_ring_bell, sc);
  }
  
  int
--- 153,174 ----
  		return;
  	}
  	sc->sc_open = 0;
! 	sc->sc_duration = 0;
! 	sc->sc_freq = 0;
! 	sc->sc_up = 0;
! 	sc->sc_down = 0;
! 	sc->sc_phase = 0;
  
  
! 	if (bus_space_read_1(sc->sc_tag, sc->sc_handle, 0x800) & 0xF0)
! 		printf(": Enhanced Apple Sound Chip");
! 	else
! 		printf(": Apple Sound Chip");
  	if (oa->oa_addr != (-1))
  		printf(" at %x", oa->oa_addr);
  	printf("\n");
  
! 	mac68k_set_bell_callback(asc_start_bell, sc);
  }
  
  int
***************
*** 284,352 ****
  	return (-1);
  }
  
! static int 
! asc_ring_bell(arg, freq, length, volume)
  	void *arg;
! 	int freq, length, volume;
  {
- 	struct asc_softc *sc = (struct asc_softc *)arg;
- 	unsigned long cfreq;
  	int i;
  
  	if (!sc)
  		return (ENODEV);
  
! 	if (sc->sc_ringing == 0) {
! 
! 		bus_space_write_multi_1(sc->sc_tag, sc->sc_handle,
! 		    0, 0, 0x800);
! 		bus_space_write_region_1(sc->sc_tag, sc->sc_handle,
! 		    0, asc_wave_tab, 0x800);
! 
! 		/* Fix this.  Need to find exact ASC sampling freq */
! 		cfreq = 65536 * freq / 466;
! 
! 		/* printf("beep: from %d, %02x %02x %02x %02x\n",
! 		 * cur_beep.freq, (cfreq >> 24) & 0xff, (cfreq >> 16) & 0xff,
! 		 * (cfreq >> 8) & 0xff, (cfreq) & 0xff); */
! 		for (i = 0; i < 8; i++) {
! 			bus_space_write_1(sc->sc_tag, sc->sc_handle,
! 			    0x814 + 8 * i, (cfreq >> 24) & 0xff);
! 			bus_space_write_1(sc->sc_tag, sc->sc_handle,
! 			    0x815 + 8 * i, (cfreq >> 16) & 0xff);
! 			bus_space_write_1(sc->sc_tag, sc->sc_handle,
! 			    0x816 + 8 * i, (cfreq >> 8) & 0xff);
! 			bus_space_write_1(sc->sc_tag, sc->sc_handle,
! 			    0x817 + 8 * i, (cfreq) & 0xff);
! 		}		/* frequency; should put cur_beep.freq in here
! 				 * somewhere. */
! 
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x807, 3); /* 44 ? */
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x806,
! 		    255 * volume / 100);
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x805, 0);
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x80f, 0);
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x802, 2); /* sampled */
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 2); /* enable sampled */
  	}
- 	sc->sc_ringing++;
- 	timeout(asc_stop_bell, sc, length);
  
! 	return (0);
  }
  
! static void 
! asc_stop_bell(arg)
  	void *arg;
  {
  	struct asc_softc *sc = (struct asc_softc *)arg;
  
! 	if (!sc)
! 		return;
! 
! 	if (sc->sc_ringing > 1000 || sc->sc_ringing < 0)
! 		panic("bell got out of sync?");
! 
! 	if (--sc->sc_ringing == 0)	/* disable ASC */
  		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 0);
  }
--- 276,356 ----
  	return (-1);
  }
  
! static int
! asc_start_bell(arg, freq, length, amplitude)
  	void *arg;
! 	int freq, length, amplitude;
  {
  	int i;
+ 	u_char temp;
+ 	struct asc_softc *sc = (struct asc_softc *)arg;
  
  	if (!sc)
  		return (ENODEV);
  
! 	/* if the bell is already ringing, ring longer */
! 	if (sc->sc_duration > 0) {
! 		sc->sc_duration += length;
! 		return(0);
  	}
  
! 	sc->sc_duration = length;
! 	sc->sc_freq = 0x11999999 / freq;
! 	sc->sc_up = 0x80 + (amplitude >> 1);
! 	sc->sc_down = 0x80 - (amplitude >> 1);
! 	sc->sc_phase = 0;
! 
! 	/* prepare the sound buffer */
! 	for (i = 1; i < 740; i+= 2) 
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, i, amplitude);
! 
! 	/* set the volume to 4 (out of 7) */
! 	bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x806, 4 << 5);
! 
! 	/* setup the ASC registers */
! 	if (bus_space_read_1(sc->sc_tag, sc->sc_handle, 0x801) != 1) {
! 		/* what does this register do? */
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x807, 0);
! 		/* select mono mode */
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x802, 0);
! 		/* select sampled sound mode */
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 1);
! 		/* what does this register do? */
! 		temp = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0x803);
! 		temp |= 0x80;
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x803, temp);
! 		temp = bus_space_read_1(sc->sc_tag, sc->sc_handle, 0x803);
! 		temp &= 0x7F;
! 		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x803, temp);
! 	} 
! 
! 	timeout(asc_ring_bell, sc, 1);
! 	return(0);
  }
  
! static void
! asc_ring_bell(arg)
  	void *arg;
  {
+ 	int i, count;
  	struct asc_softc *sc = (struct asc_softc *)arg;
  
! 	if (sc->sc_duration-- > 0) {
! 		count = 370;
! 		if (sc->sc_phase == 0)
! 			count = 498;
! 		for (i = 0; i <= count; i++) {
! 			sc->sc_phase += sc->sc_freq;
! 			if (sc->sc_phase & 0x00800000) 
! 				bus_space_write_1(sc->sc_tag, sc->sc_handle,
! 						  0, sc->sc_down);
! 			else
! 				bus_space_write_1(sc->sc_tag, sc->sc_handle,
! 						  0, sc->sc_up);
! 		}
! 		timeout(asc_ring_bell, sc, 1);
! 	} else 
  		bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 0);
+ 
+ 	return;
  }
Index: ascvar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/ascvar.h,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 ascvar.h
*** ascvar.h	1998/02/08 21:36:02	1.1.1.1
--- ascvar.h	1998/05/09 05:12:23
***************
*** 33,39 ****
  	bus_space_tag_t		sc_tag;
  	bus_space_handle_t	sc_handle;
  	int			sc_open;
! 	int			sc_ringing;
  };
  
  int	ascopen __P((dev_t dev, int flag, int mode, struct proc *p));
--- 33,45 ----
  	bus_space_tag_t		sc_tag;
  	bus_space_handle_t	sc_handle;
  	int			sc_open;
! 
! 	/* console bell state */
! 	int			sc_up;		/* up part of the wave */
! 	int			sc_down;	/* down part of the wave */
! 	int			sc_duration;	/* tone duration */
! 	int			sc_freq;	/* wave frequency */
! 	int			sc_phase;	/* current position in wave */
  };
  
  int	ascopen __P((dev_t dev, int flag, int mode, struct proc *p));
Index: ite.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/dev/ite.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 ite.c
*** ite.c	1998/02/08 21:36:05	1.1.1.1
--- ite.c	1998/05/09 05:12:27
***************
*** 159,167 ****
  static int	scrreg_bottom;
  
  /* Console bell parameters */
! static int	bell_freq = 1880;	/* frequency */
! static int	bell_length = 10;	/* duration */
! static int	bell_volume = 100;	/* volume */
  
  /* For polled ADB mode */
  static int	polledkey;
--- 159,176 ----
  static int	scrreg_bottom;
  
  /* Console bell parameters */
! #ifndef BELL_FREQ
! #define BELL_FREQ	880
! #endif
! #ifndef BELL_LENGTH
! #define BELL_LENGTH	7
! #endif
! #ifndef BELL_VOLUME
! #define BELL_VOLUME	100
! #endif
! static int	bell_freq = BELL_FREQ;		/* frequency */
! static int	bell_length = BELL_LENGTH;	/* duration */
! static int	bell_volume = BELL_VOLUME;	/* volume */
  
  /* For polled ADB mode */
  static int	polledkey;