NT4/private/ntos/nthals/halalpha/pcspeakr.c
2020-09-30 17:12:29 +02:00

137 lines
2.8 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1992, 1993 Digital Equipment Corporation
Module Name:
pcspeakr.c
Abstract:
This module implements the HAL speaker "beep" routines for the
Alpha system that use the standard PC speaker driven by an interval
timer.
Author:
Jeff McLeman (mcleman) 23-Jun-1992
Environment:
Kernel mode
Revision History:
--*/
#include "halp.h"
#include "eisa.h"
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.
--*/
{
KIRQL oldIrql;
NMI_STATUS NmiStatus;
PEISA_CONTROL controlBase;
TIMER_CONTROL timerControl;
ULONG newCount;
controlBase = HalpEisaControlBase;
//
// Raise the IRQL to dispatch level and acquire the beep spinlock.
//
KeAcquireSpinLock(&HalpBeepLock, &oldIrql);
//
// Stop the speaker.
//
*((PUCHAR) &NmiStatus) = READ_PORT_UCHAR(&controlBase->NmiStatus);
NmiStatus.SpeakerGate = 0;
NmiStatus.SpeakerData = 0;
WRITE_PORT_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus));
if (Frequency == 0) {
KeReleaseSpinLock(&HalpBeepLock, oldIrql);
return(TRUE);
}
//
// Calculate the new counter value.
//
newCount = TIMER_CLOCK_IN / Frequency;
//
// The new count must be less than 16 bits in value.
//
if (newCount >= 0x10000) {
KeReleaseSpinLock(&HalpBeepLock, oldIrql);
return(FALSE);
}
//
// Set the speaker timer to the correct mode.
//
timerControl.BcdMode = 0;
timerControl.Mode = TM_SQUARE_WAVE;
timerControl.SelectByte = SB_LSB_THEN_MSB;
timerControl.SelectCounter = SELECT_COUNTER_2;
WRITE_PORT_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));
//
// Set the speaker timer to the correct mode.
//
WRITE_PORT_UCHAR(&controlBase->SpeakerTone, (UCHAR)newCount);
WRITE_PORT_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount >> 8));
//
// Start the speaker.
//
NmiStatus.SpeakerGate = 1;
NmiStatus.SpeakerData = 1;
WRITE_PORT_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus));
//
// Release the beep spinlock and restore the IRQL.
//
KeReleaseSpinLock(&HalpBeepLock, oldIrql);
return(TRUE);
}