Author: hbelusca Date: Sun Nov 3 20:31:19 2013 New Revision: 60853
URL: http://svn.reactos.org/svn/reactos?rev=60853&view=rev Log: [NTVDM] Start to implement a basic emulated PC speaker, using the Beep driver.
Added: branches/ntvdm/subsystems/ntvdm/speaker.c (with props) branches/ntvdm/subsystems/ntvdm/speaker.h (with props) Modified: branches/ntvdm/subsystems/ntvdm/CMakeLists.txt branches/ntvdm/subsystems/ntvdm/emulator.c branches/ntvdm/subsystems/ntvdm/ntvdm.c branches/ntvdm/subsystems/ntvdm/ntvdm.h branches/ntvdm/subsystems/ntvdm/timer.c branches/ntvdm/subsystems/ntvdm/timer.h
Modified: branches/ntvdm/subsystems/ntvdm/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/CMakeList... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -12,6 +12,7 @@ registers.c timer.c ps2.c + speaker.c vga.c ntvdm.c ntvdm.rc
Modified: branches/ntvdm/subsystems/ntvdm/emulator.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator.... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -14,6 +14,7 @@ #include "bios.h" #include "bop.h" #include "dos.h" +#include "speaker.h" #include "vga.h" #include "pic.h" #include "ps2.h" @@ -122,6 +123,12 @@ case PS2_DATA_PORT: { *(Address++) = KeyboardReadData(); + break; + } + + case SPEAKER_CONTROL_PORT: + { + *(Address++) = SpeakerReadStatus(); break; }
@@ -204,6 +211,12 @@ break; }
+ case SPEAKER_CONTROL_PORT: + { + SpeakerWriteCommand(*(Address++)); + break; + } + case VGA_AC_WRITE: case VGA_AC_READ: case VGA_SEQ_INDEX:
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?r... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -13,6 +13,7 @@ #include "ntvdm.h" #include "emulator.h" #include "bios.h" +#include "speaker.h" #include "vga.h" #include "dos.h" #include "timer.h" @@ -117,6 +118,9 @@ goto Cleanup; }
+ /* Initialize the PC Speaker */ + SpeakerInitialize(); + /* Initialize the VDM DOS kernel */ if (!DosInitialize()) { @@ -133,7 +137,7 @@
/* Start the input thread */ InputThread = CreateThread(NULL, 0, &InputThreadProc, NULL, 0, NULL); - + /* Set the last timer tick to the current time */ QueryPerformanceCounter(&LastTimerTick);
@@ -187,6 +191,7 @@
Cleanup: if (InputThread != NULL) CloseHandle(InputThread); + SpeakerCleanup(); BiosCleanup(); EmulatorCleanup();
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.h?r... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/ntvdm.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/ntvdm.h [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -15,6 +15,7 @@ #include <stdarg.h> #include <conio.h>
+#define WIN32_NO_STATUS #include <windows.h>
#include <debug.h>
Added: branches/ntvdm/subsystems/ntvdm/speaker.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/speaker.c... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/speaker.c (added) +++ branches/ntvdm/subsystems/ntvdm/speaker.c [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -0,0 +1,165 @@ +/* + * COPYRIGHT: GPL - See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: speaker.c + * PURPOSE: PC Speaker emulation + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +/* INCLUDES *******************************************************************/ + +#define NDEBUG + +#include "speaker.h" +#include "emulator.h" +#include "timer.h" + +/* Extra PSDK/NDK Headers */ +#include <ndk/iofuncs.h> +#include <ndk/obfuncs.h> +#include <ndk/rtlfuncs.h> + +/* DDK Driver Headers */ +#include <ntddbeep.h> + +/* PRIVATE VARIABLES **********************************************************/ + +static BYTE Port61hState = 0x00; +HANDLE hBeep = NULL; + +/* PUBLIC FUNCTIONS ***********************************************************/ + +VOID SpeakerInitialize(VOID) +{ + NTSTATUS Status; + UNICODE_STRING BeepDevice; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK IoStatusBlock; + + /* Adapted from kernel32:Beep() */ + + // + // On TS systems, we need to Load Winsta.dll and call WinstationBeepOpen + // after doing a GetProcAddress for it + // + + /* Open the device */ + RtlInitUnicodeString(&BeepDevice, L"\Device\Beep"); + InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL); + Status = NtCreateFile(&hBeep, + FILE_READ_DATA | FILE_WRITE_DATA, + &ObjectAttributes, + &IoStatusBlock, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN_IF, + 0, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to open Beep driver, Status 0x%08lx\n", Status); + } +} + +VOID SpeakerCleanup(VOID) +{ + NtClose(hBeep); +} + +BYTE SpeakerReadStatus(VOID) +{ + // DPRINT1("SpeakerReadStatus() == 0x%x\n", Port61hState); + return Port61hState; +} + +VOID SpeakerWriteCommand(BYTE Value) +{ + BOOLEAN IsConnectedToPITChannel2; + UCHAR SpeakerData; + + // DPRINT1("SpeakerWriteCommand(0x%x)\n", Value); + + Port61hState = Value; + IsConnectedToPITChannel2 = ((Port61hState & 0x01) != 0); + SpeakerData = (Port61hState & 0x02); + + if (PitChannel2 && IsConnectedToPITChannel2) + { + /* Set bit 5 of Port 61h */ + Port61hState |= 1 << 5; + } + else + { + /* Clear bit 5 of Port 61h */ + Port61hState &= ~(1 << 5); + } + + if (PitChannel2 && IsConnectedToPITChannel2 && (SpeakerData != 0)) + { + /* Start beeping - Adapted from kernel32:Beep() */ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + BEEP_SET_PARAMETERS BeepSetParameters; + + DWORD PitChannel2ReloadValue = PitChannel2->ReloadValue; + if (PitChannel2ReloadValue == 0) PitChannel2ReloadValue = 65536; + + /* Set beep data */ + BeepSetParameters.Frequency = (PIT_BASE_FREQUENCY / PitChannel2ReloadValue) * + (PitChannel2->Mode == PIT_MODE_SQUARE_WAVE ? 2 : 1); + BeepSetParameters.Duration = INFINITE; + + /* Send the beep */ + Status = NtDeviceIoControlFile(hBeep, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_BEEP_SET, + &BeepSetParameters, + sizeof(BeepSetParameters), + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Beep (%lu, %lu) failed, Status 0x%08lx\n", + BeepSetParameters.Frequency, + BeepSetParameters.Duration, + Status); + } + } + else + { + /* Stop beeping */ + NTSTATUS Status; + IO_STATUS_BLOCK IoStatusBlock; + BEEP_SET_PARAMETERS BeepSetParameters; + + /* Set beep data */ + BeepSetParameters.Frequency = 0x00; + BeepSetParameters.Duration = 0x00; + + /* Send the beep */ + Status = NtDeviceIoControlFile(hBeep, + NULL, + NULL, + NULL, + &IoStatusBlock, + IOCTL_BEEP_SET, + &BeepSetParameters, + sizeof(BeepSetParameters), + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Beep (%lu, %lu) failed, Status 0x%08lx\n", + BeepSetParameters.Frequency, + BeepSetParameters.Duration, + Status); + } + } +} + +/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/speaker.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: branches/ntvdm/subsystems/ntvdm/speaker.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/speaker.h... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/speaker.h (added) +++ branches/ntvdm/subsystems/ntvdm/speaker.h [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -0,0 +1,29 @@ +/* + * COPYRIGHT: GPL - See COPYING in the top level directory + * PROJECT: ReactOS Virtual DOS Machine + * FILE: speaker.h + * PURPOSE: PC Speaker emulation + * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr) + */ + +#ifndef _SPEAKER_H_ +#define _SPEAKER_H_ + +/* INCLUDES *******************************************************************/ + +#include "ntvdm.h" + +/* DEFINES ********************************************************************/ + +#define SPEAKER_CONTROL_PORT 0x61 + +/* FUNCTIONS ******************************************************************/ + +VOID SpeakerInitialize(VOID); +VOID SpeakerCleanup(VOID); +BYTE SpeakerReadStatus(VOID); +VOID SpeakerWriteCommand(BYTE Value); + +#endif // _SPEAKER_H_ + +/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/speaker.h ------------------------------------------------------------------------------ svn:eol-style = native
Modified: branches/ntvdm/subsystems/ntvdm/timer.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/timer.c?r... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/timer.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/timer.c [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -16,6 +16,7 @@ /* PRIVATE VARIABLES **********************************************************/
static PIT_CHANNEL PitChannels[PIT_CHANNELS]; +PPIT_CHANNEL PitChannel2 = &PitChannels[2];
/* PUBLIC FUNCTIONS ***********************************************************/
Modified: branches/ntvdm/subsystems/ntvdm/timer.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/timer.h?r... ============================================================================== --- branches/ntvdm/subsystems/ntvdm/timer.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/ntvdm/timer.h [iso-8859-1] Sun Nov 3 20:31:19 2013 @@ -43,6 +43,8 @@ BYTE AccessMode; } PIT_CHANNEL, *PPIT_CHANNEL;
+extern PPIT_CHANNEL PitChannel2; // Needed for PC Speaker + /* FUNCTIONS ******************************************************************/
VOID PitWriteCommand(BYTE Value);