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

  1. title "Hal Beep"
  2. ;++
  3. ;
  4. ;Copyright (c) 1991 Microsoft Corporation
  5. ;
  6. ;Module Name:
  7. ;
  8. ; spbeep.asm
  9. ;
  10. ;Abstract:
  11. ;
  12. ; HAL routine to make noise. It needs to synchronize its access to the
  13. ; 8254, since we also use the 8254 for the profiling interrupt.
  14. ;
  15. ;
  16. ;Author:
  17. ;
  18. ; John Vert (jvert) 31-Jul-1991
  19. ;
  20. ;Revision History:
  21. ;
  22. ;--
  23. .386p
  24. .xlist
  25. include hal386.inc
  26. include callconv.inc ; calling convention macros
  27. include i386\kimacro.inc
  28. include mac386.inc
  29. include i386\spmp.inc
  30. .list
  31. extrn _HalpSystemHardwareLock:DWORD
  32. extrn _SpType:BYTE
  33. ;
  34. ; Defines used to program the i8254 for the speaker.
  35. ;
  36. I8254_TIMER_CONTROL_PORT EQU 43h
  37. I8254_TIMER_DATA_PORT EQU 42h
  38. I8254_TIMER_CLOCK_IN EQU 1193167
  39. I8254_TIMER_TONE_MAX EQU 65536
  40. I8254_TIMER_CONTROL_SELECT EQU 0B6h
  41. SPEAKER_CONTROL_PORT EQU 61h
  42. SPEAKER_OFF_MASK EQU 0FCh
  43. SPEAKER_ON_MASK EQU 03h
  44. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  45. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  46. page ,132
  47. subttl "HalMakeBeep"
  48. ;++
  49. ;
  50. ; BOOLEAN
  51. ; HalMakeBeep(
  52. ; IN ULONG Frequency
  53. ; )
  54. ;
  55. ; Routine Description:
  56. ;
  57. ; This function sets the frequency of the speaker, causing it to sound a
  58. ; tone. The tone will sound until the speaker is explicitly turned off,
  59. ; so the driver is responsible for controlling the duration of the tone.
  60. ;
  61. ;Arguments:
  62. ;
  63. ; Frequency - Supplies the frequency of the desired tone. A frequency of
  64. ; 0 means the speaker should be shut off.
  65. ;
  66. ;Return Value:
  67. ;
  68. ; TRUE - Operation was successful (frequency within range or zero)
  69. ; FALSE - Operation was unsuccessful (frequency was out of range)
  70. ; Current tone (if any) is unchanged.
  71. ;
  72. ;--
  73. Frequency equ [ebp + 8]
  74. cPublicProc _HalMakeBeep, 1
  75. push ebp ; save ebp
  76. mov ebp, esp ;
  77. push ebx ; save ebx
  78. Hmb10Sp:pushfd ; save flags
  79. cli ; disable interrupts
  80. lea eax, _HalpSystemHardwareLock
  81. ACQUIRE_SPINLOCK eax,Hmb99Sp
  82. cmp _SpType, SMP_SYSPRO2 ; On SysPro2 do it differently
  83. je HalMakeBeepSmp
  84. ;
  85. ; Stop the speaker.
  86. ;
  87. in al, SPEAKER_CONTROL_PORT
  88. jmp $+2
  89. and al, SPEAKER_OFF_MASK
  90. out SPEAKER_CONTROL_PORT, al
  91. jmp $+2
  92. ;
  93. ; Calculate Tone: Tone = 1.193MHz / Frequency.
  94. ; N.B. Tone must fit in 16 bits.
  95. ;
  96. mov ecx, DWORD PTR [Frequency] ; ecx <- frequency
  97. or ecx, ecx ; (ecx) == 0?
  98. je SHORT Hmb30Sp ; goto Hmb30Sp
  99. mov eax, I8254_TIMER_CLOCK_IN ; eax <- 1.193MHz, the clockin
  100. ; for the speaker tone
  101. sub edx, edx ; edx <- zero
  102. div ecx ; eax <- 1.193MHz / frequency
  103. cmp eax, I8254_TIMER_TONE_MAX ; (eax) < 2**16?
  104. jb SHORT Hmb20Sp ; goto Hmb20Sp
  105. ;
  106. ; Invalid frequency. Return FALSE.
  107. ;
  108. sub al, al
  109. jmp SHORT Hmb40Sp
  110. Hmb20Sp:
  111. ;
  112. ; Program the 8254 with the calculated tone.
  113. ;
  114. push eax ; save Tone
  115. mov al, I8254_TIMER_CONTROL_SELECT
  116. out I8254_TIMER_CONTROL_PORT, al ; select timer control register
  117. jmp $+2
  118. pop eax ; restore Tone
  119. out I8254_TIMER_DATA_PORT, al ; program 8254 with Tone lsb
  120. jmp $+2
  121. mov al, ah
  122. out I8254_TIMER_DATA_PORT, al ; program 8254 with Tone msb
  123. jmp $+2
  124. ;
  125. ; Turn the speaker on.
  126. ;
  127. in al, SPEAKER_CONTROL_PORT
  128. jmp $+2
  129. or al, SPEAKER_ON_MASK
  130. out SPEAKER_CONTROL_PORT, al
  131. jmp $+2
  132. Hmb30Sp:
  133. ;
  134. ; Return TRUE.
  135. ;
  136. mov al, 1
  137. Hmb40Sp:
  138. lea ebx, _HalpSystemHardwareLock
  139. RELEASE_SPINLOCK ebx
  140. popfd
  141. pop ebx ; restore ebx
  142. pop ebp ; restore ebp
  143. stdRET _HalMakeBeep
  144. Hmb99Sp:popfd
  145. SPIN_ON_SPINLOCK eax,<Hmb10Sp>
  146. HalMakeBeepSmp:
  147. ; A BELIZE/PHOENIX machine MUST always enable and disable the beep via
  148. ; CPU 0 regardless of the originating CPU. This is done through indexed
  149. ; IO.
  150. ;
  151. ; Note the indexed IO is serialized with the 8254 spinlock
  152. ;
  153. ; Stop the speaker.
  154. ;
  155. INDEXED_IO_READ 0,SPEAKER_CONTROL_PORT
  156. and al, SPEAKER_OFF_MASK
  157. INDEXED_IO_WRITE 0,SPEAKER_CONTROL_PORT,al
  158. ;
  159. ; Calculate Tone: Tone = 1.193MHz / Frequency.
  160. ; N.B. Tone must fit in 16 bits.
  161. ;
  162. mov ecx, DWORD PTR [Frequency] ; ecx <- frequency
  163. or ecx, ecx ; (ecx) == 0?
  164. je Hmb30Sp ; goto Hmb30
  165. mov eax, I8254_TIMER_CLOCK_IN ; eax <- 1.193MHz, the clockin
  166. ; for the speaker tone
  167. sub edx, edx ; edx <- zero
  168. div ecx ; eax <- 1.193MHz / frequency
  169. cmp eax, I8254_TIMER_TONE_MAX ; (eax) < 2**16?
  170. jb SHORT Hmb20 ; goto Hmb20
  171. ;
  172. ; Invalid frequency. Return FALSE.
  173. ;
  174. sub al, al
  175. jmp Hmb40Sp
  176. Hmb20:
  177. ;
  178. ; Program the 8254 with the calculated tone.
  179. ;
  180. push eax ; save Tone
  181. mov al, I8254_TIMER_CONTROL_SELECT
  182. INDEXED_IO_WRITE 0,I8254_TIMER_CONTROL_PORT,al
  183. pop eax ; restore Tone
  184. INDEXED_IO_WRITE 0,I8254_TIMER_DATA_PORT,al
  185. mov al, ah
  186. INDEXED_IO_WRITE 0,I8254_TIMER_DATA_PORT,al
  187. ;
  188. ; Turn the speaker on.
  189. ;
  190. INDEXED_IO_READ 0,SPEAKER_CONTROL_PORT
  191. or al, SPEAKER_ON_MASK
  192. INDEXED_IO_WRITE 0,SPEAKER_CONTROL_PORT,al
  193. jmp Hmb30Sp
  194. stdENDP _HalMakeBeep
  195. _TEXT ends
  196. end