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 /* PUBLIC FUNCTIONS ***********************************************************/
33 BYTE
SpeakerReadStatus(VOID
)
38 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 BYTE WINAPI
SpeakerReadPort(ULONG Port
)
126 return SpeakerReadStatus();
129 VOID WINAPI
SpeakerWritePort(ULONG Port
, BYTE Data
)
131 SpeakerWriteCommand(Data
);
134 VOID
SpeakerInitialize(VOID
)
137 UNICODE_STRING BeepDevice
;
138 OBJECT_ATTRIBUTES ObjectAttributes
;
139 IO_STATUS_BLOCK IoStatusBlock
;
141 /* Adapted from kernel32:Beep() */
144 // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen
145 // after doing a GetProcAddress for it
148 /* Open the device */
149 RtlInitUnicodeString(&BeepDevice
, L
"\\Device\\Beep");
150 InitializeObjectAttributes(&ObjectAttributes
, &BeepDevice
, 0, NULL
, NULL
);
151 Status
= NtCreateFile(&hBeep
,
152 FILE_READ_DATA
| FILE_WRITE_DATA
,
157 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
162 if (!NT_SUCCESS(Status
))
164 DPRINT1("Failed to open Beep driver, Status 0x%08lx\n", Status
);
167 /* Register the I/O Ports */
168 RegisterIoPort(SPEAKER_CONTROL_PORT
, SpeakerReadPort
, SpeakerWritePort
);
171 VOID
SpeakerCleanup(VOID
)