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.

154 lines
3.0 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. ixbeep.c
  5. Abstract:
  6. HAL routine to make noise. It needs to synchronize is access to the
  7. 8254, since we also use the 8254 for the profiling interrupt.
  8. Author:
  9. John Vert (jvert) 31-Jul-1991
  10. Revision History:
  11. Forrest Foltz (forrestf) 23-Oct-2000
  12. Ported from ixbeep.asm to ixbeep.c
  13. Revision History:
  14. --*/
  15. #include "halcmn.h"
  16. BOOLEAN
  17. HalMakeBeep (
  18. IN ULONG Frequency
  19. )
  20. /*++
  21. Routine Description:
  22. This function sets the frequency of the speaker, causing it to sound a
  23. tone. The tone will sound until the speaker is explicitly turned off,
  24. so the driver is responsible for controlling the duration of the tone.
  25. Arguments:
  26. Frequency - Supplies the frequency of the desired tone. A frequency of
  27. 0 means the speaker should be shut off.
  28. Return Value:
  29. TRUE - Operation was successful (frequency within range or zero)
  30. FALSE - Operation was unsuccessful (frequency was out of range)
  31. Current tone (if any) is unchanged.
  32. --*/
  33. {
  34. UCHAR value;
  35. ULONG count;
  36. BOOLEAN result;
  37. HalpAcquireSystemHardwareSpinLock();
  38. //
  39. // Stop the speaker
  40. //
  41. #if defined(NEC_98)
  42. WRITE_PORT_UCHAR(SPEAKER_CONTROL_PORT,SPEAKER_OFF);
  43. IO_DELAY();
  44. #else
  45. value = READ_PORT_UCHAR(SPEAKER_CONTROL_PORT);
  46. IO_DELAY();
  47. value &= SPEAKER_OFF_MASK;
  48. WRITE_PORT_UCHAR(SPEAKER_CONTROL_PORT,value);
  49. IO_DELAY();
  50. #endif
  51. //
  52. // If the frequency is zero, we are finished.
  53. //
  54. if (Frequency == 0) {
  55. result = TRUE;
  56. goto Exit;
  57. }
  58. //
  59. // Determine the timer register value based on the desired frequency.
  60. // If it is invalid then FALSE is returned.
  61. //
  62. count = TIMER_CLOCK_IN / Frequency;
  63. if (count > 65535) {
  64. result = FALSE;
  65. goto Exit;
  66. }
  67. #if defined(NEC_98)
  68. //
  69. // Program frequency
  70. //
  71. WRITE_PORT_UCHAR(TIMER_CONTROL_PORT,TIMER_CONTROL_SELECT);
  72. IO_DELAY();
  73. WRITE_PORT_USHORT_PAIR(TIMER_DATA_PORT,
  74. TIMER_DATA_PORT,
  75. (USHORT)count);
  76. IO_DELAY();
  77. //
  78. // Turn speaker on
  79. //
  80. WRITE_PORT_UCHAR(SPEAKER_CONTROL_PORT,SPEAKER_ON);
  81. IO_DELAY();
  82. #else
  83. //
  84. // Put channel 2 in mode 3 (square-wave generator) and load the
  85. // proper value in.
  86. //
  87. WRITE_PORT_UCHAR(TIMER1_CONTROL_PORT,
  88. TIMER_COMMAND_COUNTER2 +
  89. TIMER_COMMAND_RW_16BIT +
  90. TIMER_COMMAND_MODE3);
  91. IO_DELAY();
  92. WRITE_PORT_USHORT_PAIR (TIMER1_DATA_PORT2,
  93. TIMER1_DATA_PORT2,
  94. (USHORT)count);
  95. IO_DELAY();
  96. //
  97. // Turn the speaker on
  98. //
  99. value = READ_PORT_UCHAR(SPEAKER_CONTROL_PORT); IO_DELAY();
  100. value |= SPEAKER_ON_MASK;
  101. WRITE_PORT_UCHAR(SPEAKER_CONTROL_PORT,value); IO_DELAY();
  102. #endif // NEC_98
  103. //
  104. // Indicate success, we're done
  105. //
  106. result = TRUE;
  107. Exit:
  108. HalpReleaseSystemHardwareSpinLock();
  109. return result;
  110. }