summaryrefslogtreecommitdiffstats
path: root/private/ntos/nthals/halx86/i386/ixbeep.asm
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/nthals/halx86/i386/ixbeep.asm')
-rw-r--r--private/ntos/nthals/halx86/i386/ixbeep.asm181
1 files changed, 181 insertions, 0 deletions
diff --git a/private/ntos/nthals/halx86/i386/ixbeep.asm b/private/ntos/nthals/halx86/i386/ixbeep.asm
new file mode 100644
index 000000000..0722ca9df
--- /dev/null
+++ b/private/ntos/nthals/halx86/i386/ixbeep.asm
@@ -0,0 +1,181 @@
+ title "Hal Beep"
+;++
+;
+;Copyright (c) 1991 Microsoft Corporation
+;
+;Module Name:
+;
+; ixbeep.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
+ .list
+
+ extrn _Halp8254Lock:DWORD
+
+;
+; 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$03 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
+Hmb10: pushfd ; save flags
+ cli ; disable interrupts
+
+ifndef NT_UP
+ lea eax, _Halp8254Lock
+ ACQUIRE_SPINLOCK eax,Hmb99
+endif
+
+ ;
+ ; 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 Hmb30 ; 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 SHORT Hmb40
+Hmb20:
+ ;
+ ; 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
+
+Hmb30:
+ ;
+ ; Return TRUE.
+ ;
+
+ mov al, 1
+
+Hmb40:
+ifndef NT_UP
+ lea ebx, _Halp8254Lock
+ RELEASE_SPINLOCK ebx
+endif
+
+ popfd
+ pop ebx ; restore ebx
+ pop ebp ; restore ebp
+ stdRET _HalMakeBeep
+
+ifndef NT_UP
+
+Hmb99: popfd
+ SPIN_ON_SPINLOCK eax,<Hmb10>
+
+endif
+
+stdENDP _HalMakeBeep
+
+_TEXT$03 ends
+ end