2 * COPYRIGHT: GPL - See COPYING in the top level directory
3 * PROJECT: ReactOS Virtual DOS Machine
5 * PURPOSE: PC Speaker emulation
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
9 /* INCLUDES *******************************************************************/
18 /* Extra PSDK/NDK Headers */
19 #include <ndk/iofuncs.h>
20 #include <ndk/obfuncs.h>
21 #include <ndk/rtlfuncs.h>
23 /* DDK Driver Headers */
26 /* PRIVATE VARIABLES **********************************************************/
28 static BYTE Port61hState
= 0x00;
31 /* PRIVATE FUNCTIONS **********************************************************/
33 static BYTE
SpeakerReadStatus(VOID
)
38 static VOID
SpeakerWriteCommand(BYTE Value
)
40 BOOLEAN IsConnectedToPITChannel2
;
44 IsConnectedToPITChannel2
= ((Port61hState
& 0x01) != 0);
45 SpeakerData
= (Port61hState
& 0x02);
47 if (PitChannel2
&& IsConnectedToPITChannel2
)
49 /* Set bit 5 of Port 61h */
50 Port61hState
|= 1 << 5;
54 /* Clear bit 5 of Port 61h */
55 Port61hState
&= ~(1 << 5);
58 if (PitChannel2
&& IsConnectedToPITChannel2
&& (SpeakerData
!= 0))
60 /* Start beeping - Adapted from kernel32:Beep() */
62 IO_STATUS_BLOCK IoStatusBlock
;
63 BEEP_SET_PARAMETERS BeepSetParameters
;
65 DWORD PitChannel2ReloadValue
= PitChannel2
->ReloadValue
;
66 if (PitChannel2ReloadValue
== 0) PitChannel2ReloadValue
= 65536;
69 BeepSetParameters
.Frequency
= (PIT_BASE_FREQUENCY
/ PitChannel2ReloadValue
) *
70 (PitChannel2
->Mode
== PIT_MODE_SQUARE_WAVE
? 2 : 1);
71 BeepSetParameters
.Duration
= INFINITE
;
74 Status
= NtDeviceIoControlFile(hBeep
,
81 sizeof(BeepSetParameters
),
84 if (!NT_SUCCESS(Status
))
86 DPRINT1("Beep (%lu, %lu) failed, Status 0x%08lx\n",
87 BeepSetParameters
.Frequency
,
88 BeepSetParameters
.Duration
,
96 IO_STATUS_BLOCK IoStatusBlock
;
97 BEEP_SET_PARAMETERS BeepSetParameters
;
100 BeepSetParameters
.Frequency
= 0x00;
101 BeepSetParameters
.Duration
= 0x00;
104 Status
= NtDeviceIoControlFile(hBeep
,
111 sizeof(BeepSetParameters
),
114 if (!NT_SUCCESS(Status
))
116 DPRINT1("Beep (%lu, %lu) failed, Status 0x%08lx\n",
117 BeepSetParameters
.Frequency
,
118 BeepSetParameters
.Duration
,
124 static BYTE WINAPI
SpeakerReadPort(ULONG Port
)
126 return SpeakerReadStatus();
129 static VOID WINAPI
SpeakerWritePort(ULONG Port
, BYTE Data
)
131 SpeakerWriteCommand(Data
);
134 /* PUBLIC FUNCTIONS ***********************************************************/
136 VOID
SpeakerInitialize(VOID
)
139 UNICODE_STRING BeepDevice
;
140 OBJECT_ATTRIBUTES ObjectAttributes
;
141 IO_STATUS_BLOCK IoStatusBlock
;
143 /* Adapted from kernel32:Beep() */
146 // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
147 // after doing a GetProcAddress for it
150 /* Open the device */
151 RtlInitUnicodeString(&BeepDevice
, L
"\\Device\\Beep");
152 InitializeObjectAttributes(&ObjectAttributes
, &BeepDevice
, 0, NULL
, NULL
);
153 Status
= NtCreateFile(&hBeep
,
154 FILE_READ_DATA
| FILE_WRITE_DATA
,
159 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
164 if (!NT_SUCCESS(Status
))
166 DPRINT1("Failed to open Beep driver, Status 0x%08lx\n", Status
);
169 /* Register the I/O Ports */
170 RegisterIoPort(SPEAKER_CONTROL_PORT
, SpeakerReadPort
, SpeakerWritePort
);
173 VOID
SpeakerCleanup(VOID
)