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/CMakeLis…
==============================================================================
--- 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?…
==============================================================================
--- 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?…
==============================================================================
--- 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.…
==============================================================================
--- 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(a)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.…
==============================================================================
--- 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(a)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?…
==============================================================================
--- 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?…
==============================================================================
--- 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);