158 lines
6.8 KiB
Markdown
158 lines
6.8 KiB
Markdown
---
|
||
created_at: '2015-01-13T05:08:05.000Z'
|
||
title: What’s up with the Beep driver in Windows 7? (2010)
|
||
url: http://blogs.msdn.com/b/larryosterman/archive/2010/01/04/what-s-up-with-the-beep-driver-in-windows-7.aspx
|
||
author: lunixbochs
|
||
points: 125
|
||
story_text: ''
|
||
comment_text:
|
||
num_comments: 33
|
||
story_id:
|
||
story_title:
|
||
story_url:
|
||
parent_id:
|
||
created_at_i: 1421125685
|
||
_tags:
|
||
- story
|
||
- author_lunixbochs
|
||
- story_8878267
|
||
objectID: '8878267'
|
||
year: 2010
|
||
|
||
---
|
||
Earlier today, someone asked me why 64bit versions of windows don’t
|
||
support the internal PC speaker beeps. The answer is somewhat
|
||
complicated and ends up being an interesting intersection between a host
|
||
of conflicting tensions in the PC ecosystem.
|
||
|
||
|
||
|
||
Let’s start by talking about how the Beep hardware worked way back in
|
||
the day\[1\]. The original IBM PC contained an Intel 8254 programmable
|
||
interval timer chip to manage the system clock. Because the IBM
|
||
engineers felt that the PC needed to be able to play sound (but not
|
||
particularly high quality sound), they decided that they could use the
|
||
8254 as a very primitive square wave generator. To do this, they
|
||
programmed the 3rd timer on the chip to operate in Square Wave mode and
|
||
to count down with the desired output frequency. This caused the Out2
|
||
line on the chip to toggle from high to low every time the clock went to
|
||
0. The hardware designers tied the Out2 line on the chip to the PC
|
||
speaker and voila – they were able to use the clock chip to program the
|
||
PC speaker to make a noise (not a very high quality noise but a noise
|
||
nonetheless).
|
||
|
||
The Beep() Win32 API is basically a thin wrapper around the 8254 PIC
|
||
functionality. So when you call the Beep() API, you program the 8254 to
|
||
play sounds on the PC speaker.
|
||
|
||
|
||
|
||
Fast forward about 25 years… The PC industry has largely changed and
|
||
the PC architecture has changed with it. At this point they don’t
|
||
actually use the 8254 as the programmable interrupt controller, but it’s
|
||
still in modern PCs. And that’s because the 8254 is still used to drive
|
||
the PC speaker.
|
||
|
||
One of the other things that happened in the intervening 25 years was
|
||
that machines got a whole lot more capable. Now machines come with
|
||
capabilities like newfangled hard disk drives (some of which can even
|
||
hold more than 30 megabytes of storage (but I don’t know why on earth
|
||
anyone would ever want a hard disk that can hold that much stuff)). And
|
||
every non server machine sold today has a PC sound card. So every
|
||
single machine sold today has two ways of generating sounds – the PC
|
||
sound card and the old 8254 which is tied to the internal PC speaker (or
|
||
to a dedicated input on the sound card – more on this later).
|
||
|
||
|
||
|
||
There’s something else that happened in the past 25 years. PCs became
|
||
commodity systems. And that started exerting a huge amount of pressure
|
||
on PC manufacturers to cut costs. They looked at the 8254 and asked
|
||
“why can’t we remove this?”
|
||
|
||
It turns out that they couldn’t. And the answer to why they couldn’t
|
||
came from a totally unexpected place. The [American’s with Disabilities
|
||
Act](http://www.ada.gov/).
|
||
|
||
|
||
|
||
The ADA? What on earth could the ADA have to do with a PC making a
|
||
beep? Well it turns out that at some point in the intervening 25
|
||
years, the Win32 Beep() was used for assistive technologies – in
|
||
particular the sounds made when you enable the assistive technologies
|
||
like [StickyKeys](http://en.wikipedia.org/wiki/Sticky_keys) were
|
||
generated using the Beep() API. There are about 6 different assistive
|
||
technology (AT) sounds built into windows, their implementation is
|
||
plumbed fairly deep inside the win32k.sys driver.
|
||
|
||
But why does that matter? Well it turns out that many enterprises (both
|
||
governments and corporations) have requirements that prevent them from
|
||
purchasing equipment that lacks accessible technologies and that meant
|
||
that you couldn’t sell computers that didn’t have beep hardware to those
|
||
enterprises.
|
||
|
||
|
||
|
||
This issue was first noticed when Microsoft was developing the first
|
||
64bit version of WIndows. Because the original 64bit windows was
|
||
intended for servers, the hardware requirements for 64bit machines
|
||
didn’t include support for an 8254 (apparently the AT requirements are
|
||
relaxed on servers). But when we started building a client 64bit OS, we
|
||
had a problem – client OS’s had to support AT so we needed to bring the
|
||
beep back even on machines that didn’t have beep hardware.
|
||
|
||
For Windows XP this was solved with some custom code in winlogon which
|
||
worked but had some unexpected complications (none of which are relevant
|
||
to this discussion). For Windows Vista, I redesigned the mechanism to
|
||
move the accessibility beep logic to a new “user mode system sounds
|
||
agent”.
|
||
|
||
Because the only machines with this problem were 64bit machines, this
|
||
functionality was restricted to 64bit versions of Windows.
|
||
|
||
That in turn meant that PC manufacturers still had to include support
|
||
for the 8254 hardware – after all if the user chose to buy the machine
|
||
with a 32bit operating system on it they might want to use the AT
|
||
functionality.
|
||
|
||
For Windows 7, we resolved the issue completely – we moved all the
|
||
functionality that used to be contained in Beep.Sys into the user mode
|
||
system sounds agent – now when you call the Beep() API instead of
|
||
manipulating the 8254 chip the call is re-routed into a user mode agent
|
||
which actually plays the sounds.
|
||
|
||
|
||
|
||
There was another benefit associated with this plan: Remember above when
|
||
I mentioned that the 8254 output line was tied to a dedicated input on
|
||
the sound card? Because of this input to the sound card, the sound
|
||
hardware needed to stay powered on at full power all the time because
|
||
the system couldn’t know when an application might call Beep and thus
|
||
activate the 8254 (there’s no connection between the 8254 and the power
|
||
management infrastructure so the system can’t power on the sound
|
||
hardware when someone programs the 3rd timer on the 8254). By
|
||
redirecting the Beep calls through the system audio hardware the system
|
||
was able to put the sound hardware to sleep until it was needed.
|
||
|
||
|
||
|
||
This redirection also had had a couple of unexpected benefits. For
|
||
instance when you accidentally type (or grep) through a file containing
|
||
0x07 characters in it (like a .obj file) you can finally turn off the
|
||
annoying noise – since the beeps are played through the PC speakers, the
|
||
PC mute key works to shut them up. It also means that you can now
|
||
control the volume of the beeps.
|
||
|
||
There were also some unexpected consequences. The biggest was that
|
||
people started noticing when applications called Beep(). They had
|
||
placed their PCs far enough away (or there was enough ambient noise)
|
||
that they had never noticed when their PC was beeping at them until the
|
||
sounds started coming out their speakers.
|
||
|
||
|
||
|
||
|
||
|
||
\[1\] Thus providing me with an justification to keep my old Intel
|
||
component data catalogs from back in the 1980s.
|