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.

206 lines
5.7 KiB

  1. title "Hal Beep"
  2. ;++
  3. ;
  4. ;Copyright (c) 1991 Microsoft Corporation
  5. ;
  6. ;Module Name:
  7. ;
  8. ; ixbeep.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. .list
  30. EXTRNP _HalpAcquireSystemHardwareSpinLock,0
  31. EXTRNP _HalpReleaseSystemHardwareSpinLock,0
  32. ;
  33. ; Defines used to program the i8254 for the speaker.
  34. ;
  35. ifdef NEC_98
  36. I8254_TIMER_CONTROL_PORT equ 3fdfh ; write mode port (for N mode)
  37. I8254_TIMER_DATA_PORT equ 3fdbh ; count port (for N mode)
  38. I8254_TIMER_CLOCK_IN equ 2457600
  39. I8254_TIMER_TONE_MAX equ 65536
  40. I8254_TIMER_CONTROL_SELECT equ 76h
  41. SPEAKER_CONTROL_PORT equ 37h ; system port C, set command port
  42. SPEAKER_OFF equ 07h
  43. SPEAKER_ON equ 06h
  44. else ; NEC_98
  45. I8254_TIMER_CONTROL_PORT EQU 43h
  46. I8254_TIMER_DATA_PORT EQU 42h
  47. I8254_TIMER_CLOCK_IN EQU 1193167
  48. I8254_TIMER_TONE_MAX EQU 65536
  49. I8254_TIMER_CONTROL_SELECT EQU 0B6h
  50. SPEAKER_CONTROL_PORT EQU 61h
  51. SPEAKER_OFF_MASK EQU 0FCh
  52. SPEAKER_ON_MASK EQU 03h
  53. endif ; NEC_98
  54. _TEXT$03 SEGMENT DWORD PUBLIC 'CODE'
  55. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  56. page ,132
  57. subttl "HalMakeBeep"
  58. ;++
  59. ;
  60. ; BOOLEAN
  61. ; HalMakeBeep(
  62. ; IN ULONG Frequency
  63. ; )
  64. ;
  65. ; Routine Description:
  66. ;
  67. ; This function sets the frequency of the speaker, causing it to sound a
  68. ; tone. The tone will sound until the speaker is explicitly turned off,
  69. ; so the driver is responsible for controlling the duration of the tone.
  70. ;
  71. ;Arguments:
  72. ;
  73. ; Frequency - Supplies the frequency of the desired tone. A frequency of
  74. ; 0 means the speaker should be shut off.
  75. ;
  76. ;Return Value:
  77. ;
  78. ; TRUE - Operation was successful (frequency within range or zero)
  79. ; FALSE - Operation was unsuccessful (frequency was out of range)
  80. ; Current tone (if any) is unchanged.
  81. ;
  82. ;--
  83. Frequency equ [ebp + 8]
  84. cPublicProc _HalMakeBeep , 1
  85. push ebp ; save ebp
  86. mov ebp, esp ;
  87. stdCall _HalpAcquireSystemHardwareSpinLock ; intr disabled
  88. ;
  89. ; Stop the speaker.
  90. ;
  91. ifdef NEC_98
  92. mov al, SPEAKER_OFF
  93. out SPEAKER_CONTROL_PORT, al
  94. out 5Fh, al ; IoDelay
  95. else ; NEC_98
  96. in al, SPEAKER_CONTROL_PORT
  97. jmp $+2
  98. and al, SPEAKER_OFF_MASK
  99. out SPEAKER_CONTROL_PORT, al
  100. jmp $+2
  101. endif ; NEC_98
  102. ;
  103. ; Calculate Tone: Tone = 1.193MHz / Frequency.
  104. ; N.B. Tone must fit in 16 bits.
  105. ;
  106. mov ecx, DWORD PTR [Frequency] ; ecx <- frequency
  107. or ecx, ecx ; (ecx) == 0?
  108. je SHORT Hmb30 ; goto Hmb30
  109. mov eax, I8254_TIMER_CLOCK_IN ; eax <- 1.193MHz, the clockin
  110. ; for the speaker tone
  111. sub edx, edx ; edx <- zero
  112. div ecx ; eax <- 1.193MHz / frequency
  113. cmp eax, I8254_TIMER_TONE_MAX ; (eax) < 2**16?
  114. jb SHORT Hmb20 ; goto Hmb20
  115. ;
  116. ; Invalid frequency. Return FALSE.
  117. ;
  118. sub al, al
  119. jmp SHORT Hmb40
  120. Hmb20:
  121. ;
  122. ; Program the 8254 with the calculated tone.
  123. ;
  124. ifdef NEC_98
  125. mov dx, I8254_TIMER_CONTROL_PORT ; port address for N
  126. mov cx, I8254_TIMER_DATA_PORT
  127. push eax ; save Tone
  128. mov al, I8254_TIMER_CONTROL_SELECT
  129. out dx, al ; select timer control register
  130. out 5Fh, al ; IoDelay
  131. pop eax ; restore Tone
  132. mov dx, cx ; set 'write mode' port addr
  133. out dx, al ; program 8254 with Tone lsb
  134. out 5Fh, al ; IoDelay
  135. mov al, ah
  136. out dx, al ; program 8254 with Tone msb
  137. out 5Fh, al ; IoDelay
  138. ;
  139. ; Turn the speaker on.
  140. ;
  141. mov al,SPEAKER_ON
  142. out SPEAKER_CONTROL_PORT, al
  143. out 5Fh, al ; IoDelay
  144. else ; NEC_98
  145. push eax ; save Tone
  146. mov al, I8254_TIMER_CONTROL_SELECT
  147. out I8254_TIMER_CONTROL_PORT, al ; select timer control register
  148. jmp $+2
  149. pop eax ; restore Tone
  150. out I8254_TIMER_DATA_PORT, al ; program 8254 with Tone lsb
  151. jmp $+2
  152. mov al, ah
  153. out I8254_TIMER_DATA_PORT, al ; program 8254 with Tone msb
  154. jmp $+2
  155. ;
  156. ; Turn the speaker on.
  157. ;
  158. in al, SPEAKER_CONTROL_PORT
  159. jmp $+2
  160. or al, SPEAKER_ON_MASK
  161. out SPEAKER_CONTROL_PORT, al
  162. jmp $+2
  163. endif ; NEC_98
  164. Hmb30:
  165. ;
  166. ; Return TRUE.
  167. ;
  168. mov al, 1
  169. Hmb40:
  170. stdCall _HalpReleaseSystemHardwareSpinLock
  171. pop ebp ; restore ebp
  172. stdRET _HalMakeBeep
  173. stdENDP _HalMakeBeep
  174. _TEXT$03 ends
  175. end