Subject: Patch for console bell.
To: None <port-mac68k@netbsd.org>
From: Frederick Bruckman <fb@enteract.com>
List: port-mac68k
Date: 08/22/1998 03:46:04
This is a patch that Colin Wood posted in May. It's been reworked to apply
against current-Aug. 21, 1998. This patch gives you a sweet sounding
console bell on machines with the Extended Apple Sound Chip. If typing ^G
on the console of your mac68k-netbsd box gives you an alarming, static-y
clicking sound, then you probably have an EASC.

You apply this patch against your kernel sources. If, for example, you've
saved this message as /root/patch-bell, do

	# cd /usr ; patch </root/patch-bell

then build your kernel. No changes from the GENERIC config are necessary,
but if you have a custom kernel, be sure to include an asc device:

# On-board audio hardware
asc0    at obio?                        # ASC/EASC audio

You may optionally customize the sound of the bell. The example that
follows is my preference; it's a lower, longer tone than the default.

options         BELL_FREQ=1441
options         BELL_LENGTH=11
options         BELL_VOLUME=88

Here's the patch:

*** src/sys/arch/mac68k/obio/ascvar.h.orig	Sun May  3 06:12:43 1998
--- src/sys/arch/mac68k/obio/ascvar.h	Fri Aug 21 12:57:21 1998
***************
*** 32,40 ****
  	struct device		sc_dev;
  	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));
  int	ascclose __P((dev_t dev, int flag, int mode, struct proc *p));
--- 32,46 ----
  	struct device		sc_dev;
  	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));
  int	ascclose __P((dev_t dev, int flag, int mode, struct proc *p));
*** src/sys/arch/mac68k/obio/asc.c.orig	Sat Aug 15 06:12:11 1998
--- src/sys/arch/mac68k/obio/asc.c	Fri Aug 21 13:15:55 1998
***************
*** 94,105 ****
  #ifdef ASC_DEBUG
  int	asc_debug = 0;		/* non-zero enables debugging output */
  #endif
  
! 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 void	asc_intr_enable __P((void));
  static void	asc_intr __P((void *));
  
  static int	ascmatch __P((struct device *, struct cfdata *, void *));
--- 94,104 ----
  #ifdef ASC_DEBUG
  int	asc_debug = 0;		/* non-zero enables debugging output */
  #endif
  
! static int    asc_start_bell __P((void *, int, int, int));
! static void   asc_ring_bell __P((void *));
  
  static void	asc_intr_enable __P((void));
  static void	asc_intr __P((void *));
  
  static int	ascmatch __P((struct device *, struct cfdata *, void *));
***************
*** 149,157 ****
  {
  	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))
  		addr = (bus_addr_t)oa->oa_addr;
--- 148,155 ----
***************
*** 164,192 ****
  		printf(": can't map memory space\n");
  		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);
  
  	via2_register_irq(VIA2_ASC, asc_intr, sc);
  	asc_intr_enable();
  }
--- 162,185 ----
  		printf(": can't map memory space\n");
  		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);
  
  	via2_register_irq(VIA2_ASC, asc_intr, sc);
  	asc_intr_enable();
  }
***************
*** 295,367 ****
  
  	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);
  }
  
  static void
  asc_intr_enable()
--- 288,372 ----
  
  	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;
  }
  
  static void
  asc_intr_enable()
*** src/sys/arch/mac68k/dev/ite.c.orig	Fri Jul  3 06:09:59 1998
--- src/sys/arch/mac68k/dev/ite.c	Fri Aug 21 12:57:37 1998
***************
*** 160,170 ****
  static int	scrreg_top;		/* scroll region */
  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;
  extern int	adb_polling;
--- 160,179 ----
  static int	scrreg_top;		/* scroll region */
  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;
  extern int	adb_polling;