Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

246 lines
6.4 KiB

title "Hal Beep"
;++
;
;Copyright (c) 1991 Microsoft Corporation
;
;Module Name:
;
; spbeep.asm
;
;Abstract:
;
; HAL routine to make noise. It needs to synchronize its access to the
; 8254, since we also use the 8254 for the profiling interrupt.
;
;
;Author:
;
; John Vert (jvert) 31-Jul-1991
;
;Revision History:
;
;--
.386p
.xlist
include hal386.inc
include callconv.inc ; calling convention macros
include i386\kimacro.inc
include mac386.inc
include i386\spmp.inc
.list
extrn _HalpSystemHardwareLock:DWORD
extrn _SpType:BYTE
;
; Defines used to program the i8254 for the speaker.
;
I8254_TIMER_CONTROL_PORT EQU 43h
I8254_TIMER_DATA_PORT EQU 42h
I8254_TIMER_CLOCK_IN EQU 1193167
I8254_TIMER_TONE_MAX EQU 65536
I8254_TIMER_CONTROL_SELECT EQU 0B6h
SPEAKER_CONTROL_PORT EQU 61h
SPEAKER_OFF_MASK EQU 0FCh
SPEAKER_ON_MASK EQU 03h
_TEXT SEGMENT DWORD PUBLIC 'CODE'
ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
page ,132
subttl "HalMakeBeep"
;++
;
; BOOLEAN
; HalMakeBeep(
; IN ULONG Frequency
; )
;
; Routine Description:
;
; This function sets the frequency of the speaker, causing it to sound a
; tone. The tone will sound until the speaker is explicitly turned off,
; so the driver is responsible for controlling the duration of the tone.
;
;Arguments:
;
; Frequency - Supplies the frequency of the desired tone. A frequency of
; 0 means the speaker should be shut off.
;
;Return Value:
;
; TRUE - Operation was successful (frequency within range or zero)
; FALSE - Operation was unsuccessful (frequency was out of range)
; Current tone (if any) is unchanged.
;
;--
Frequency equ [ebp + 8]
cPublicProc _HalMakeBeep, 1
push ebp ; save ebp
mov ebp, esp ;
push ebx ; save ebx
Hmb10Sp:pushfd ; save flags
cli ; disable interrupts
lea eax, _HalpSystemHardwareLock
ACQUIRE_SPINLOCK eax,Hmb99Sp
cmp _SpType, SMP_SYSPRO2 ; On SysPro2 do it differently
je HalMakeBeepSmp
;
; Stop the speaker.
;
in al, SPEAKER_CONTROL_PORT
jmp $+2
and al, SPEAKER_OFF_MASK
out SPEAKER_CONTROL_PORT, al
jmp $+2
;
; Calculate Tone: Tone = 1.193MHz / Frequency.
; N.B. Tone must fit in 16 bits.
;
mov ecx, DWORD PTR [Frequency] ; ecx <- frequency
or ecx, ecx ; (ecx) == 0?
je SHORT Hmb30Sp ; goto Hmb30Sp
mov eax, I8254_TIMER_CLOCK_IN ; eax <- 1.193MHz, the clockin
; for the speaker tone
sub edx, edx ; edx <- zero
div ecx ; eax <- 1.193MHz / frequency
cmp eax, I8254_TIMER_TONE_MAX ; (eax) < 2**16?
jb SHORT Hmb20Sp ; goto Hmb20Sp
;
; Invalid frequency. Return FALSE.
;
sub al, al
jmp SHORT Hmb40Sp
Hmb20Sp:
;
; Program the 8254 with the calculated tone.
;
push eax ; save Tone
mov al, I8254_TIMER_CONTROL_SELECT
out I8254_TIMER_CONTROL_PORT, al ; select timer control register
jmp $+2
pop eax ; restore Tone
out I8254_TIMER_DATA_PORT, al ; program 8254 with Tone lsb
jmp $+2
mov al, ah
out I8254_TIMER_DATA_PORT, al ; program 8254 with Tone msb
jmp $+2
;
; Turn the speaker on.
;
in al, SPEAKER_CONTROL_PORT
jmp $+2
or al, SPEAKER_ON_MASK
out SPEAKER_CONTROL_PORT, al
jmp $+2
Hmb30Sp:
;
; Return TRUE.
;
mov al, 1
Hmb40Sp:
lea ebx, _HalpSystemHardwareLock
RELEASE_SPINLOCK ebx
popfd
pop ebx ; restore ebx
pop ebp ; restore ebp
stdRET _HalMakeBeep
Hmb99Sp:popfd
SPIN_ON_SPINLOCK eax,<Hmb10Sp>
HalMakeBeepSmp:
; A BELIZE/PHOENIX machine MUST always enable and disable the beep via
; CPU 0 regardless of the originating CPU. This is done through indexed
; IO.
;
; Note the indexed IO is serialized with the 8254 spinlock
;
; Stop the speaker.
;
INDEXED_IO_READ 0,SPEAKER_CONTROL_PORT
and al, SPEAKER_OFF_MASK
INDEXED_IO_WRITE 0,SPEAKER_CONTROL_PORT,al
;
; Calculate Tone: Tone = 1.193MHz / Frequency.
; N.B. Tone must fit in 16 bits.
;
mov ecx, DWORD PTR [Frequency] ; ecx <- frequency
or ecx, ecx ; (ecx) == 0?
je Hmb30Sp ; goto Hmb30
mov eax, I8254_TIMER_CLOCK_IN ; eax <- 1.193MHz, the clockin
; for the speaker tone
sub edx, edx ; edx <- zero
div ecx ; eax <- 1.193MHz / frequency
cmp eax, I8254_TIMER_TONE_MAX ; (eax) < 2**16?
jb SHORT Hmb20 ; goto Hmb20
;
; Invalid frequency. Return FALSE.
;
sub al, al
jmp Hmb40Sp
Hmb20:
;
; Program the 8254 with the calculated tone.
;
push eax ; save Tone
mov al, I8254_TIMER_CONTROL_SELECT
INDEXED_IO_WRITE 0,I8254_TIMER_CONTROL_PORT,al
pop eax ; restore Tone
INDEXED_IO_WRITE 0,I8254_TIMER_DATA_PORT,al
mov al, ah
INDEXED_IO_WRITE 0,I8254_TIMER_DATA_PORT,al
;
; Turn the speaker on.
;
INDEXED_IO_READ 0,SPEAKER_CONTROL_PORT
or al, SPEAKER_ON_MASK
INDEXED_IO_WRITE 0,SPEAKER_CONTROL_PORT,al
jmp Hmb30Sp
stdENDP _HalMakeBeep
_TEXT ends
end