mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 15:36:04 +00:00
[NTVDM]
- For the BIOS wait hack, use the NT API instead of the Win32 one. - Remove unneeded DOS-exported functions. - Use a PitGetReloadValue function for retrieving the reload value of a given PIT channel, instead of directly reading the reload value member, for functions *outside* of the PIT module. - Implement basic Pulse-Width Modulation code for the PC speaker emulation. svn path=/trunk/; revision=65333
This commit is contained in:
parent
7cfea2fbb6
commit
6990cd2172
7 changed files with 236 additions and 61 deletions
|
@ -31,6 +31,9 @@
|
||||||
#include "hardware/pic.h"
|
#include "hardware/pic.h"
|
||||||
#include "hardware/timer.h"
|
#include "hardware/timer.h"
|
||||||
|
|
||||||
|
/* Extra PSDK/NDK Headers */
|
||||||
|
#include <ndk/kefuncs.h>
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
CALLBACK16 BiosContext;
|
CALLBACK16 BiosContext;
|
||||||
|
@ -166,9 +169,11 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
|
||||||
* See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
|
* See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
|
||||||
* for more information.
|
* for more information.
|
||||||
*/
|
*/
|
||||||
|
LARGE_INTEGER TimeOut;
|
||||||
|
TimeOut.QuadPart = MAKELONG(getDX(), getCX()) * -10LL;
|
||||||
|
|
||||||
// HACK: For now, use the Win32 API (that takes time in milliseconds).
|
// HACK: For now, use the NT API (time in hundreds of nanoseconds).
|
||||||
Sleep(MAKELONG(getDX(), getCX()) / 1000);
|
NtDelayExecution(FALSE, &TimeOut);
|
||||||
|
|
||||||
/* Clear CF */
|
/* Clear CF */
|
||||||
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
|
||||||
|
|
|
@ -239,11 +239,6 @@ DWORD DosStartProcess(IN LPCSTR ExecutablePath,
|
||||||
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
|
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
|
||||||
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);
|
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);
|
||||||
|
|
||||||
VOID WINAPI DosInt20h(LPWORD Stack);
|
|
||||||
VOID WINAPI DosInt21h(LPWORD Stack);
|
|
||||||
VOID WINAPI DosBreakInterrupt(LPWORD Stack);
|
|
||||||
VOID WINAPI DosInt2Fh(LPWORD Stack);
|
|
||||||
|
|
||||||
BOOLEAN DosKRNLInitialize(VOID);
|
BOOLEAN DosKRNLInitialize(VOID);
|
||||||
|
|
||||||
#endif // _DOS_H_
|
#endif // _DOS_H_
|
||||||
|
|
|
@ -293,8 +293,8 @@ static VOID WINAPI Port61hWrite(USHORT Port, BYTE Data)
|
||||||
DPRINT("Speaker %s\n", Port61hState & 0x02 ? "on" : "off");
|
DPRINT("Speaker %s\n", Port61hState & 0x02 ? "on" : "off");
|
||||||
// SpeakerStateChange = TRUE;
|
// SpeakerStateChange = TRUE;
|
||||||
}
|
}
|
||||||
// if (SpeakerStateChange) SpeakerChange();
|
// if (SpeakerStateChange) SpeakerChange(Port61hState);
|
||||||
SpeakerChange();
|
SpeakerChange(Port61hState);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VOID WINAPI PitChan0Out(LPVOID Param, BOOLEAN State)
|
static VOID WINAPI PitChan0Out(LPVOID Param, BOOLEAN State)
|
||||||
|
@ -347,7 +347,7 @@ static VOID WINAPI PitChan2Out(LPVOID Param, BOOLEAN State)
|
||||||
if ((OldPort61hState ^ Port61hState) & 0x20)
|
if ((OldPort61hState ^ Port61hState) & 0x20)
|
||||||
{
|
{
|
||||||
DPRINT("PitChan2Out -- Port61hState changed\n");
|
DPRINT("PitChan2Out -- Port61hState changed\n");
|
||||||
SpeakerChange();
|
SpeakerChange(Port61hState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include "emulator.h"
|
#include "emulator.h"
|
||||||
#include "speaker.h"
|
#include "speaker.h"
|
||||||
#include "io.h"
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
/* Extra PSDK/NDK Headers */
|
/* Extra PSDK/NDK Headers */
|
||||||
|
@ -20,6 +19,9 @@
|
||||||
#include <ndk/obfuncs.h>
|
#include <ndk/obfuncs.h>
|
||||||
#include <ndk/rtlfuncs.h>
|
#include <ndk/rtlfuncs.h>
|
||||||
|
|
||||||
|
/* Extra PSDK/NDK Headers */
|
||||||
|
#include <ndk/kefuncs.h>
|
||||||
|
|
||||||
/* DDK Driver Headers */
|
/* DDK Driver Headers */
|
||||||
#include <ntddbeep.h>
|
#include <ntddbeep.h>
|
||||||
|
|
||||||
|
@ -27,26 +29,56 @@
|
||||||
|
|
||||||
static HANDLE hBeep = NULL;
|
static HANDLE hBeep = NULL;
|
||||||
|
|
||||||
|
static LARGE_INTEGER FreqCount, CountStart;
|
||||||
|
static ULONG PulseTickCount = 0, FreqPulses = 0;
|
||||||
|
|
||||||
|
#define SPEAKER_RESPONSE 200 // in milliseconds
|
||||||
|
|
||||||
|
#define MIN_AUDIBLE_FREQ 20 // BEEP_FREQUENCY_MINIMUM
|
||||||
|
#define MAX_AUDIBLE_FREQ 20000 // BEEP_FREQUENCY_MAXIMUM
|
||||||
|
#define CLICK_FREQ 100
|
||||||
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
static DWORD OldReloadValue = 0;
|
static
|
||||||
static PIT_MODE OldMode = 0;
|
VOID
|
||||||
|
MakeBeep(ULONG Frequency,
|
||||||
/* PUBLIC FUNCTIONS ***********************************************************/
|
ULONG Duration)
|
||||||
|
|
||||||
VOID PlaySound(DWORD Frequency,
|
|
||||||
DWORD Duration)
|
|
||||||
{
|
{
|
||||||
/* Adapted from kernel32:Beep() */
|
static ULONG LastFrequency = 0, LastDuration = 0;
|
||||||
|
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
BEEP_SET_PARAMETERS BeepSetParameters;
|
BEEP_SET_PARAMETERS BeepSetParameters;
|
||||||
|
|
||||||
/* Set beep data */
|
/*
|
||||||
|
* Do nothing if we are replaying exactly the same sound
|
||||||
|
* (this avoids hiccups due to redoing the same beeps).
|
||||||
|
*/
|
||||||
|
if (Frequency == LastFrequency && Duration == LastDuration) return;
|
||||||
|
|
||||||
|
/* A null frequency means we stop beeping */
|
||||||
|
if (Frequency == 0) Duration = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For small durations we automatically reset the beep so
|
||||||
|
* that we can replay short beeps like clicks immediately.
|
||||||
|
*/
|
||||||
|
if (Duration < 10)
|
||||||
|
{
|
||||||
|
LastFrequency = 0;
|
||||||
|
LastDuration = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LastFrequency = Frequency;
|
||||||
|
LastDuration = Duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the data and do the beep */
|
||||||
BeepSetParameters.Frequency = Frequency;
|
BeepSetParameters.Frequency = Frequency;
|
||||||
BeepSetParameters.Duration = Duration;
|
BeepSetParameters.Duration = Duration;
|
||||||
|
|
||||||
/* Send the beep */
|
|
||||||
NtDeviceIoControlFile(hBeep,
|
NtDeviceIoControlFile(hBeep,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -59,44 +91,173 @@ VOID PlaySound(DWORD Frequency,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID SpeakerChange(VOID)
|
static
|
||||||
|
VOID PulseSample(VOID)
|
||||||
{
|
{
|
||||||
BYTE Port61hState = IOReadB(CONTROL_SYSTEM_PORT61H);
|
static ULONG Pulses = 0, CountStartTick = 0, LastPulsesFreq = 0;
|
||||||
BOOLEAN IsConnectedToPITChannel2 = !!(Port61hState & 0x01);
|
ULONG LastPulseTickCount, CurrPulsesFreq;
|
||||||
BOOLEAN SpeakerDataOn = !!(Port61hState & 0x02);
|
LARGE_INTEGER Counter;
|
||||||
|
LONGLONG Elapsed;
|
||||||
|
|
||||||
if (PitChannel2 && IsConnectedToPITChannel2 && SpeakerDataOn)
|
/*
|
||||||
|
* Check how far away was the previous pulse and
|
||||||
|
* if it was >= 200ms away then restart counting.
|
||||||
|
*/
|
||||||
|
LastPulseTickCount = PulseTickCount;
|
||||||
|
PulseTickCount = GetTickCount();
|
||||||
|
if (PulseTickCount - LastPulseTickCount >= SPEAKER_RESPONSE)
|
||||||
{
|
{
|
||||||
/* Start beeping */
|
CountStart.QuadPart = 0;
|
||||||
|
Pulses = 0;
|
||||||
|
FreqPulses = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD Frequency, Duration;
|
/* We have closely spaced pulses. Start counting. */
|
||||||
|
if (CountStart.QuadPart == 0)
|
||||||
|
{
|
||||||
|
NtQueryPerformanceCounter(&CountStart, NULL);
|
||||||
|
CountStartTick = PulseTickCount;
|
||||||
|
Pulses = 0;
|
||||||
|
FreqPulses = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DWORD PitChannel2ReloadValue = PitChannel2->ReloadValue;
|
/* A pulse is ongoing */
|
||||||
if (PitChannel2ReloadValue == 0) PitChannel2ReloadValue = 65536;
|
++Pulses;
|
||||||
|
|
||||||
DPRINT("(1) PitChannel2(Mode = %d ; ReloadValue = %d)\n", PitChannel2->Mode, PitChannel2ReloadValue);
|
/* We require some pulses to have some statistics */
|
||||||
|
if (PulseTickCount - CountStartTick <= (SPEAKER_RESPONSE >> 1)) return;
|
||||||
|
|
||||||
if (OldMode == PitChannel2->Mode && OldReloadValue == PitChannel2ReloadValue)
|
/* Get count time */
|
||||||
return;
|
NtQueryPerformanceCounter(&Counter, NULL);
|
||||||
|
|
||||||
OldMode = PitChannel2->Mode;
|
/*
|
||||||
OldReloadValue = PitChannel2ReloadValue;
|
* Get the number of speaker hundreds of microseconds that have passed
|
||||||
|
* since we started counting.
|
||||||
|
*/
|
||||||
|
Elapsed = (Counter.QuadPart - CountStart.QuadPart) * 10000 / FreqCount.QuadPart;
|
||||||
|
if (Elapsed == 0) ++Elapsed;
|
||||||
|
|
||||||
DPRINT("(2) PitChannel2(Mode = %d ; ReloadValue = %d)\n", PitChannel2->Mode, PitChannel2ReloadValue);
|
/* Update counting for next pulses */
|
||||||
|
CountStart = Counter;
|
||||||
|
CountStartTick = PulseTickCount;
|
||||||
|
|
||||||
Frequency = (PIT_BASE_FREQUENCY / PitChannel2ReloadValue);
|
// HACKHACK!! I need to check why we need to double the number
|
||||||
Duration = INFINITE;
|
// of pulses in order to have the correct frequency...
|
||||||
|
Pulses <<= 1;
|
||||||
|
|
||||||
PlaySound(Frequency, Duration);
|
/* Get the current pulses frequency */
|
||||||
|
CurrPulsesFreq = 10000 * Pulses / Elapsed;
|
||||||
|
|
||||||
|
/* Round the current pulses frequency up and align */
|
||||||
|
if ((CurrPulsesFreq & 0x0F) > 7) CurrPulsesFreq += 0x10;
|
||||||
|
CurrPulsesFreq &= ~0x0F;
|
||||||
|
|
||||||
|
/* Reinitialize frequency counters if necessary */
|
||||||
|
if (LastPulsesFreq == 0) LastPulsesFreq = CurrPulsesFreq;
|
||||||
|
if (FreqPulses == 0) FreqPulses = LastPulsesFreq;
|
||||||
|
|
||||||
|
/* Fix up the current pulses frequency if needed */
|
||||||
|
if (LastPulsesFreq != 0 && CurrPulsesFreq == 0)
|
||||||
|
CurrPulsesFreq = LastPulsesFreq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Magic begins there...
|
||||||
|
*/
|
||||||
|
#ifndef ABS
|
||||||
|
#define ABS(x) ((x) < 0 ? -(x) : (x))
|
||||||
|
#endif
|
||||||
|
if (ABS(CurrPulsesFreq - LastPulsesFreq) > 7)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This can be a "large" fluctuation so ignore it for now, but take
|
||||||
|
* it into account if it happens to be a real frequency change.
|
||||||
|
*/
|
||||||
|
CurrPulsesFreq = (CurrPulsesFreq + LastPulsesFreq) >> 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Stop beeping */
|
// FreqPulses = ((FreqPulses << 2) + LastPulsesFreq + CurrPulsesFreq) / 6;
|
||||||
|
FreqPulses = ((FreqPulses << 1) + LastPulsesFreq + CurrPulsesFreq) >> 2;
|
||||||
|
}
|
||||||
|
|
||||||
OldMode = 0;
|
/* Round the pulses frequency up and align */
|
||||||
OldReloadValue = 0;
|
if ((FreqPulses & 0x0F) > 7) FreqPulses += 0x10;
|
||||||
|
FreqPulses &= ~0x0F;
|
||||||
|
|
||||||
PlaySound(0x00, 0x00);
|
DPRINT("FreqPulses = %d, LastPulsesFreq = %d, CurrPulsesFreq = %d, Pulses = %d, Elapsed = %d\n",
|
||||||
|
FreqPulses, LastPulsesFreq, CurrPulsesFreq, Pulses, Elapsed);
|
||||||
|
|
||||||
|
LastPulsesFreq = CurrPulsesFreq;
|
||||||
|
Pulses = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
||||||
|
|
||||||
|
// SpeakerPulse
|
||||||
|
VOID SpeakerChange(UCHAR Port61hValue)
|
||||||
|
{
|
||||||
|
static BOOLEAN OldSpeakerOff = TRUE;
|
||||||
|
|
||||||
|
BOOLEAN Timer2Gate = !!(Port61hValue & 0x01);
|
||||||
|
BOOLEAN SpeakerOn = !!(Port61hValue & 0x02);
|
||||||
|
|
||||||
|
DPRINT("SpeakerChange -- Timer2Gate == %s ; SpeakerOn == %s\n",
|
||||||
|
Timer2Gate ? "true" : "false", SpeakerOn ? "true" : "false");
|
||||||
|
|
||||||
|
if (Timer2Gate)
|
||||||
|
{
|
||||||
|
if (SpeakerOn)
|
||||||
|
{
|
||||||
|
/* Start beeping */
|
||||||
|
ULONG Frequency = (PIT_BASE_FREQUENCY / PitGetReloadValue(2));
|
||||||
|
if (Frequency < MIN_AUDIBLE_FREQ || MAX_AUDIBLE_FREQ < Frequency)
|
||||||
|
Frequency = 0;
|
||||||
|
|
||||||
|
MakeBeep(Frequency, INFINITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Stop beeping */
|
||||||
|
MakeBeep(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (SpeakerOn)
|
||||||
|
{
|
||||||
|
if (OldSpeakerOff)
|
||||||
|
{
|
||||||
|
OldSpeakerOff = FALSE;
|
||||||
|
PulseSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FreqPulses >= MIN_AUDIBLE_FREQ)
|
||||||
|
MakeBeep(FreqPulses, INFINITE);
|
||||||
|
else if (CountStart.QuadPart != 0)
|
||||||
|
MakeBeep(CLICK_FREQ, 1); /* Click */
|
||||||
|
else
|
||||||
|
MakeBeep(0, 0); /* Stop beeping */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OldSpeakerOff = TRUE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check how far away was the previous pulse and if
|
||||||
|
* it was >= (200 + eps) ms away then stop beeping.
|
||||||
|
*/
|
||||||
|
if (GetTickCount() - PulseTickCount >= SPEAKER_RESPONSE + (SPEAKER_RESPONSE >> 3))
|
||||||
|
{
|
||||||
|
CountStart.QuadPart = 0;
|
||||||
|
FreqPulses = 0;
|
||||||
|
|
||||||
|
/* Stop beeping */
|
||||||
|
MakeBeep(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,9 +268,14 @@ VOID SpeakerInitialize(VOID)
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
|
|
||||||
/* Adapted from kernel32:Beep() */
|
/* Retrieve the performance frequency and initialize the timer ticks */
|
||||||
|
NtQueryPerformanceCounter(&CountStart, &FreqCount);
|
||||||
|
if (FreqCount.QuadPart == 0)
|
||||||
|
{
|
||||||
|
wprintf(L"FATAL: Performance counter not available\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Open the device */
|
/* Open the BEEP device */
|
||||||
RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep");
|
RtlInitUnicodeString(&BeepDevice, L"\\Device\\Beep");
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL);
|
InitializeObjectAttributes(&ObjectAttributes, &BeepDevice, 0, NULL, NULL);
|
||||||
Status = NtCreateFile(&hBeep,
|
Status = NtCreateFile(&hBeep,
|
||||||
|
@ -125,7 +291,8 @@ VOID SpeakerInitialize(VOID)
|
||||||
0);
|
0);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Failed to open Beep driver, Status 0x%08lx\n", Status);
|
DPRINT1("Failed to open the Beep driver, Status 0x%08lx\n", Status);
|
||||||
|
// hBeep = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
VOID SpeakerChange(VOID);
|
VOID SpeakerChange(UCHAR Port61hValue);
|
||||||
|
|
||||||
VOID SpeakerInitialize(VOID);
|
VOID SpeakerInitialize(VOID);
|
||||||
VOID SpeakerCleanup(VOID);
|
VOID SpeakerCleanup(VOID);
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
static PIT_CHANNEL PitChannels[PIT_CHANNELS];
|
static PIT_CHANNEL PitChannels[PIT_CHANNELS];
|
||||||
PPIT_CHANNEL PitChannel2 = &PitChannels[2];
|
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
@ -471,22 +470,19 @@ VOID PitSetGate(BYTE Channel, BOOLEAN State)
|
||||||
PitChannels[Channel].Gate = State;
|
PitChannels[Channel].Gate = State;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID PitClock(DWORD Count)
|
WORD PitGetReloadValue(BYTE Channel)
|
||||||
{
|
{
|
||||||
UINT i;
|
if (Channel >= PIT_CHANNELS) return 0xFFFF;
|
||||||
|
|
||||||
if (Count == 0) return;
|
if (PitChannels[Channel].ReloadValue == 0)
|
||||||
|
return 0xFFFF;
|
||||||
for (i = 0; i < PIT_CHANNELS; i++)
|
else
|
||||||
{
|
return PitChannels[Channel].ReloadValue;
|
||||||
// if (!PitChannels[i].Counting) continue;
|
|
||||||
PitDecrementCount(&PitChannels[i], Count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD PitGetResolution(VOID)
|
DWORD PitGetResolution(VOID)
|
||||||
{
|
{
|
||||||
INT i;
|
UCHAR i;
|
||||||
DWORD MinReloadValue = 65536;
|
DWORD MinReloadValue = 65536;
|
||||||
|
|
||||||
for (i = 0; i < PIT_CHANNELS; i++)
|
for (i = 0; i < PIT_CHANNELS; i++)
|
||||||
|
@ -503,6 +499,19 @@ DWORD PitGetResolution(VOID)
|
||||||
return PIT_BASE_FREQUENCY / MinReloadValue;
|
return PIT_BASE_FREQUENCY / MinReloadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID PitClock(DWORD Count)
|
||||||
|
{
|
||||||
|
UCHAR i;
|
||||||
|
|
||||||
|
if (Count == 0) return;
|
||||||
|
|
||||||
|
for (i = 0; i < PIT_CHANNELS; i++)
|
||||||
|
{
|
||||||
|
// if (!PitChannels[i].Counting) continue;
|
||||||
|
PitDecrementCount(&PitChannels[i], Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VOID PitInitialize(VOID)
|
VOID PitInitialize(VOID)
|
||||||
{
|
{
|
||||||
/* Set up the timers to their default value */
|
/* Set up the timers to their default value */
|
||||||
|
|
|
@ -73,15 +73,14 @@ typedef struct _PIT_CHANNEL
|
||||||
|
|
||||||
} PIT_CHANNEL, *PPIT_CHANNEL;
|
} PIT_CHANNEL, *PPIT_CHANNEL;
|
||||||
|
|
||||||
extern PPIT_CHANNEL PitChannel2; // Needed for PC Speaker
|
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
VOID PitSetOutFunction(BYTE Channel, LPVOID Param, PIT_OUT_FUNCTION OutFunction);
|
VOID PitSetOutFunction(BYTE Channel, LPVOID Param, PIT_OUT_FUNCTION OutFunction);
|
||||||
VOID PitSetGate(BYTE Channel, BOOLEAN State);
|
VOID PitSetGate(BYTE Channel, BOOLEAN State);
|
||||||
|
WORD PitGetReloadValue(BYTE Channel);
|
||||||
|
|
||||||
VOID PitClock(DWORD Count);
|
|
||||||
DWORD PitGetResolution(VOID);
|
DWORD PitGetResolution(VOID);
|
||||||
|
VOID PitClock(DWORD Count);
|
||||||
|
|
||||||
VOID PitInitialize(VOID);
|
VOID PitInitialize(VOID);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue