Author: silverblade Date: Tue Jul 1 17:02:54 2008 New Revision: 34242
URL: http://svn.reactos.org/svn/reactos?rev=34242&view=rev Log: Implemented sound library routines for obtaining Sound Blaster DSP chip version, speaker on/off and DSP 4.xx sample rate configuration. Renamed functions to shorter names. Updated test code in sb16_nt4. DSP version is reported as 4.05 in VirtualBox - which seems to report invalid speaker status... Finally, updated e-mail address.
Modified: branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c branches/silverblade-audio/include/reactos/libs/sound/devname.h branches/silverblade-audio/include/reactos/libs/sound/midi.h branches/silverblade-audio/include/reactos/libs/sound/midiuart.h branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h branches/silverblade-audio/include/reactos/libs/sound/time.h branches/silverblade-audio/lib/drivers/sound/devname.c branches/silverblade-audio/lib/drivers/sound/hardware.c branches/silverblade-audio/lib/drivers/sound/midiuart.c branches/silverblade-audio/lib/drivers/sound/sbdsp.c branches/silverblade-audio/lib/drivers/sound/time.c
Modified: branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/drivers/multim... ============================================================================== --- branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c [iso-8859-1] (original) +++ branches/silverblade-audio/drivers/multimedia/audio/sb16_nt4/main.c [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -4,10 +4,16 @@ NT4 driver model
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 25 May 2008 - Created + + Notes: + ** This driver is currently solely being used to test the sound + library, which actually implements the main body of the driver. This + will eventually be replaced with a proper driver. It assumes a + configuration of base port 0x220, IRQ 5, DMA channel 1 ** */
#include <ntddk.h> @@ -17,6 +23,9 @@ #include <sbdsp.h> #include <devname.h>
+#define SB_DEFAULT_TIMEOUT 1000 + + typedef struct _SOUND_BLASTER_EXTENSION { ULONG NothingHereYet; @@ -90,7 +99,8 @@ UnloadSoundBlaster( IN PDRIVER_OBJECT DriverObject) { - INFO_(IHVAUDIO, "Sound Blaster driver being unloaded"); + DbgPrint("Sound Blaster driver being unloaded\n"); + /*INFO_(IHVAUDIO, "Sound Blaster driver being unloaded");*/ }
/* This is to be moved into the sound library later */ @@ -145,17 +155,64 @@
ie, this is pretty much as non-PnP as you can get! */ + STDCALL NTSTATUS ThisIsSparta(IN PDRIVER_OBJECT DriverObject) { DEVICE_OBJECT device; - BOOLEAN result; - CreateSoundDeviceWithDefaultName(DriverObject, 0, 69, 0, &device); - - INFO_(IHVAUDIO, "Resetting SB..."); - result = ResetSoundBlasterDSP((PUCHAR)0x220, 10000); - INFO_(IHVAUDIO, "SB reset returns %d", result); + NTSTATUS result; + BOOLEAN speaker_state = TRUE; + UCHAR major = 0x69, minor = 0x96; + + /*CreateSoundDeviceWithDefaultName(DriverObject, 0, 69, 0, &device);*/ + + /* 0x220 is the port we expect to work */ + DbgPrint("Resetting Sound Blaster DSP at 0x220\n"); + result = SbDspReset((PUCHAR)0x220, SB_DEFAULT_TIMEOUT); + DbgPrint("Reset was %s\n", + NT_SUCCESS(result) ? "successful" : "unsuccessful"); + + /* 0x240, we don't expect to work */ + DbgPrint("Resetting Sound Blaster DSP at 0x240\n"); + result = SbDspReset((PUCHAR)0x240, SB_DEFAULT_TIMEOUT); + DbgPrint("Reset was %s\n", + NT_SUCCESS(result) ? "successful" : "unsuccessful"); + + /* Try getting version */ + DbgPrint("Retrieving Sound Blaster version...\n"); + result = SbDspGetVersion((PUCHAR)0x220, &major, &minor, SB_DEFAULT_TIMEOUT); + + DbgPrint("Version retrival was %s\n", + NT_SUCCESS(result) ? "successful" : "unsuccessful"); + DbgPrint("Sound Blaster DSP version is %d.%02d\n", major, minor); + + result = SbDspIsSpeakerEnabled((PUCHAR)0x220, &speaker_state, SB_DEFAULT_TIMEOUT); + DbgPrint("Speaker state retrieval %s\n", + NT_SUCCESS(result) ? "succeeded" : "failed"); + + DbgPrint("Speaker state is presently %s\n", + speaker_state ? "ENABLED" : "DISABLED"); + + result = SbDspEnableSpeaker((PUCHAR)0x220, SB_DEFAULT_TIMEOUT); + DbgPrint("Speaker enable request %s\n", + NT_SUCCESS(result) ? "succeeded" : "failed"); + + result = SbDspIsSpeakerEnabled((PUCHAR)0x220, &speaker_state, SB_DEFAULT_TIMEOUT); + DbgPrint("Speaker state retrieval %s\n", + NT_SUCCESS(result) ? "succeeded" : "failed"); + DbgPrint("Speaker state is now %s\n", + speaker_state ? "ENABLED" : "DISABLED"); + + result = SbDspDisableSpeaker((PUCHAR)0x220, SB_DEFAULT_TIMEOUT); + DbgPrint("Speaker disable request %s\n", + NT_SUCCESS(result) ? "succeeded" : "failed"); + + result = SbDspIsSpeakerEnabled((PUCHAR)0x220, &speaker_state, SB_DEFAULT_TIMEOUT); + DbgPrint("Speaker state retrieval %s\n", + NT_SUCCESS(result) ? "succeeded" : "failed"); + DbgPrint("Speaker state is now %s\n", + speaker_state ? "ENABLED" : "DISABLED");
return STATUS_SUCCESS; } @@ -169,7 +226,8 @@ { NTSTATUS status;
- INFO_(IHVAUDIO, "Sound Blaster driver (NT4 model) by Silver Blade"); + DbgPrint("Sound Blaster driver (NT4 model) by Silver Blade\n"); + /*INFO_(IHVAUDIO, "Sound Blaster driver (NT4 model) by Silver Blade");*/
DriverObject->Flags = 0;
@@ -183,4 +241,3 @@ /* Hax */ return ThisIsSparta(DriverObject); } -
Modified: branches/silverblade-audio/include/reactos/libs/sound/devname.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/devname.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/devname.h [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ Device naming & creation helper routines
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 25 May 2008 - Created
Modified: branches/silverblade-audio/include/reactos/libs/sound/midi.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/midi.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/midi.h [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ MIDI constants
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 26 May 2008 - Created
Modified: branches/silverblade-audio/include/reactos/libs/sound/midiuart.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/midiuart.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/midiuart.h [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ MIDI UART support
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 26 May 2008 - Created
Modified: branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/sbdsp.h [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,13 +3,13 @@ Sound Blaster DSP support
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 26 May 2008 - Created
Notes: - ... + Where timeouts are concerned, a value of 0 is interpreted as "forever". */
#ifndef ROS_SOUND_SBDSP_H @@ -42,11 +42,13 @@ #define WRITE_SB_DSP_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x0C, x) #define WRITE_SB_DSP_COMMAND(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x0C, x)
-#define READ_SB_DSP_WRITE_BUFFER_STATUS(bp) \ - ( READ_PORT_UCHAR((PUCHAR) bp+0x0C) & 0x01 ) +/* Clear to send */ +#define SB_DSP_CLEAR_TO_SEND(bp) \ + ( ! (READ_PORT_UCHAR((PUCHAR) bp+0x0C) & 0x80 ) )
-#define READ_SB_DSP_READ_BUFFER_STATUS(bp) \ - ( READ_PORT_UCHAR((PUCHAR) bp+0x0E) & 0x01 ) +/* Data available for reading */ +#define SB_DSP_DATA_AVAILABLE(bp) \ + ( READ_PORT_UCHAR((PUCHAR) bp+0x0E) & 0x80 )
#define SB_DSP_READY 0xAA @@ -65,23 +67,120 @@
/* - Routines + Reset the Sound Blaster DSP. */ -BOOLEAN -ResetSoundBlasterDSP( +NTSTATUS +SbDspReset( IN PUCHAR BasePort, IN ULONG Timeout);
-BOOLEAN -WaitForSoundBlasterDSPReady( +/* + Wait for the Sound Blaster DSP to be ready for data to be written to it. +*/ +NTSTATUS +SbDspWaitToWrite( IN PUCHAR BasePort, IN ULONG Timeout);
+/* + Wait for data to be ready for reading from the Sound Blaster DSP. +*/ NTSTATUS -GetSoundBlasterDSPVersion( +SbDspWaitToRead( + IN PUCHAR BasePort, + IN ULONG Timeout); + +/* + Wait for the Sound Blaster DSP to be ready for data to be written to it, + then (providing it becomes ready within the timeout period), write the + data to it. +*/ +NTSTATUS +SbDspWrite( + IN PUCHAR BasePort, + IN UCHAR DataByte, + IN ULONG Timeout); + +/* + Wait for the Sound Blaster DSP to be ready for data to be read from it, + then read the data from it into the pointer supplied as DataByte. If + the timeout is exceeded, DataByte will not be modified. +*/ +NTSTATUS +SbDspRead( + IN PUCHAR BasePort, + OUT PUCHAR DataByte, + IN ULONG Timeout); + +/* + This can only be called immediately after a reset has been issued. The + major version and minor version are returned in MajorVersion and + MinorVersion, respectively. + + The timeout applies to each DSP read/write performed. Note that the + data pointed to by MajorVersion may still fail if the retrieval of + MinorVersion times out. +*/ +NTSTATUS +SbDspGetVersion( IN PUCHAR BasePort, OUT PUCHAR MajorVersion, OUT PUCHAR MinorVersion, IN ULONG Timeout);
+/* + Turn the speaker on. +*/ +NTSTATUS +SbDspEnableSpeaker( + IN PUCHAR BasePort, + IN ULONG Timeout); + +/* + Turn the speaker off. +*/ +NTSTATUS +SbDspDisableSpeaker( + IN PUCHAR BasePort, + IN ULONG Timeout); + +/* + Obtains the speaker status, storing the result in IsEnabled. This will be + TRUE if the speaker is enabled, otherwise FALSE. +*/ +NTSTATUS +SbDspIsSpeakerEnabled( + IN PUCHAR BasePort, + OUT PBOOLEAN IsEnabled, + IN ULONG Timeout); + +/* + Validate the sample rate + * DSP 4.xx only +*/ +BOOLEAN +SbDspIsValidRate( + IN USHORT Rate); + +/* + Set the output/playback rate + * DSP 4.xx only +*/ +NTSTATUS +SbDspSetOutputRate( + IN PUCHAR BasePort, + IN USHORT Rate, + IN ULONG Timeout); + +/* + Set the input/record rate + * DSP 4.xx only +*/ +NTSTATUS +SbDspSetInputRate( + IN PUCHAR BasePort, + IN USHORT Rate, + IN ULONG Timeout); + + #endif
Modified: branches/silverblade-audio/include/reactos/libs/sound/time.h URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/include/reacto... ============================================================================== --- branches/silverblade-audio/include/reactos/libs/sound/time.h [iso-8859-1] (original) +++ branches/silverblade-audio/include/reactos/libs/sound/time.h [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ Timing helper
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 1 July 2008 - Created
Modified: branches/silverblade-audio/lib/drivers/sound/devname.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/devname.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/devname.c [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ Device naming & creation helper routines
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 25 May 2008 - Created @@ -12,6 +12,7 @@ #include <ntddk.h> #include <ntddsnd.h> #include <debug.h> +
/* Default device names @@ -81,14 +82,14 @@ /* Check for NULL parameters */ if ( ( ! Path ) || ( ! DeviceName ) ) { - ERR_(IHVAUDIO, "Unexpected NULL parameter"); + DPRINT("Unexpected NULL parameter"); return STATUS_INVALID_PARAMETER; }
/* Range-check */ if ( Index >= SOUND_MAX_DEVICES ) { - ERR_(IHVAUDIO, "Device index %d out of range", Index); + DPRINT("Device index %d out of range", Index); return STATUS_INVALID_PARAMETER; }
@@ -106,7 +107,7 @@
if ( ! DeviceName->Buffer ) { - ERR_(IHVAUDIO, "Couldn't allocate memory for device name string"); + DPRINT("Couldn't allocate memory for device name string"); return STATUS_INSUFFICIENT_RESOURCES; }
@@ -171,7 +172,7 @@
if ( DeviceType > MAX_DEVICE_TYPE ) { - ERR_(IHVAUDIO, "Invalid device type"); + DPRINT("Invalid device type"); return STATUS_INVALID_PARAMETER; }
@@ -206,14 +207,14 @@ if ( ( ! DeviceNameBody ) || ( ! DosDeviceNameBody ) || ( ! FullDeviceName ) || ( ! FullDosDeviceName ) ) { - ERR_(IHVAUDIO, "Unexpected NULL parameter"); + DPRINT("Unexpected NULL parameter"); return STATUS_INVALID_PARAMETER; }
/* Range-check */ if ( Index >= SOUND_MAX_DEVICES ) { - ERR_(IHVAUDIO, "Device %d exceeds maximum", Index); + DPRINT("Device %d exceeds maximum", Index); return STATUS_INVALID_PARAMETER; }
@@ -264,14 +265,14 @@ if ( ( ! DriverObject ) || ( ! DeviceObject ) || ( ! WideDeviceName ) || ( ! WideDosDeviceName ) ) { - ERR_(IHVAUDIO, "Unexpected NULL parameter"); + DPRINT("Unexpected NULL parameter"); return STATUS_INVALID_PARAMETER; }
/* Range-check */ if ( Index >= SOUND_MAX_DEVICES ) { - ERR_(IHVAUDIO, "Device index %d exceeds maximum", Index); + DPRINT("Device index %d exceeds maximum", Index); return STATUS_INVALID_PARAMETER; }
@@ -345,14 +346,14 @@ /* Check for NULL parameters */ if ( ( ! DriverObject ) || ( ! DeviceObject ) ) { - ERR_(IHVAUDIO, "Unexpected NULL parameter"); + DPRINT("Unexpected NULL parameter"); return STATUS_INVALID_PARAMETER; }
/* Range-check */ if ( Index >= SOUND_MAX_DEVICES ) { - ERR_(IHVAUDIO, "Device index %d exceeds maximum", Index); + DPRINT("Device index %d exceeds maximum", Index); return STATUS_INVALID_PARAMETER; }
Modified: branches/silverblade-audio/lib/drivers/sound/hardware.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/hardware.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/hardware.c [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ Hardware interaction helper
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 25 May 2008 - Created @@ -33,7 +33,7 @@ KIRQL IrqLevel; KAFFINITY Affinity;
- INFO_(IHVAUDIO, "Obtaining interrupt vector"); + DPRINT("Obtaining interrupt vector");
Vector = HalGetInterruptVector(Isa, 0, @@ -42,8 +42,8 @@ &IrqLevel, &Affinity);
- INFO_(IHVAUDIO, "Vector %d", Vector); - INFO_(IHVAUDIO, "Connecting IRQ %d", Irq); + DPRINT("Vector %d", Vector); + DPRINT("Connecting IRQ %d", Irq);
Status = IoConnectInterrupt(InterruptObject, ServiceRoutine,
Modified: branches/silverblade-audio/lib/drivers/sound/midiuart.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/midiuart.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/midiuart.c [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,7 +3,7 @@ MIDI UART support
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 26 May 2008 - Created @@ -91,82 +91,3 @@
return TRUE; } - - -/* Experimental OO-style stuff */ -/* -typedef struct _MIDIUART -{ - PUCHAR BasePort; - ULONG Timeout; -} MIDIUART, *PMIDIUART; - -NTSTATUS -MidiUart_Create( - IN PUCHAR BasePort, - IN ULONG Timeout, - OUT PMIDIUART* MidiUart) -{ - PMIDIUART NewMidiUart; - - if ( ! MidiUart ) - return STATUS_INVALID_PARAMETER; - - NewMidiUart = ExAllocatePoolWithTag(sizeof(MIDIUART), PAGED_POOL, 'MIDU'); - - if ( ! NewMidiUart ) - return STATUS_INSUFFICIENT_RESOURCES; - - NewMidiUart->BasePort = BasePort; - NewMidiUart->Timeout = Timeout; - - *MidiUart = NewMidiUart; - - return STATUS_SUCCESS; -} - -BOOLEAN -MidiUart_WaitForStatus( - IN PMIDIUART MidiUart, - IN UCHAR StatusFlags) -{ - if ( ! MidiUart) - return FALSE; - - return WaitForMidiUartStatus(MidiUart->BasePort, - StatusFlags, - MidiUart->Timeout); -} - -#define MidiUart_WaitForCTS(inst) \ - MidiUart_WaitForStatus(inst, MIDIUART_STATUS_CTS) - -#define MidiUart_WaitForDTR(inst) \ - MidiUart_WaitForStatus(inst, MIDIUART_STATUS_DTR) - -BOOLEAN -MidiUart_WriteByte( - IN PMIDIUART MidiUart, - IN UCHAR Data) -{ - if ( ! MidiUart ) - return FALSE; - - return WriteMidiUartByte(MidiUart->BasePort, - Data, - MidiUart->Timeout); -} - -BOOLEAN -MidiUart_ReadByte( - IN PMIDIUART MidiUart, - OUT PUCHAR Data) -{ - if ( ! MidiUart ) - return FALSE; - - return ReadMidiUartByte(MidiUart->BasePort, - Data, - MidiUart->Timeout); -} -*/
Modified: branches/silverblade-audio/lib/drivers/sound/sbdsp.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/sbdsp.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/sbdsp.c [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,33 +3,32 @@ Sound Blaster DSP support
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 26 May 2008 - Created
Notes: - ... + Functions documented in sbdsp.h */
#include <ntddk.h> +#include <debug.h>
#include <time.h> #include <sbdsp.h>
-BOOLEAN -ResetSoundBlasterDSP( +NTSTATUS +SbDspReset( IN PUCHAR BasePort, IN ULONG Timeout) { ULONG Expiry; - KTIMER Timer; KIRQL CurrentIrqLevel = KeGetCurrentIrql(); + BOOLEAN DataAvailable = FALSE;
/* Should be called from DriverEntry with this IRQL */ ASSERT(CurrentIrqLevel == PASSIVE_LEVEL); - - KeInitializeTimer(&Timer);
WRITE_SB_DSP_RESET(BasePort, 0x01); SleepMs(50); /* Should be enough */ @@ -37,19 +36,35 @@
Expiry = QuerySystemTimeMs() + Timeout;
+ /* Wait for data to be available */ while ( (QuerySystemTimeMs() < Expiry) || ( Timeout == 0) ) { + if ( SB_DSP_DATA_AVAILABLE(BasePort) ) + { + DataAvailable = TRUE; + break; + } + } + + if ( ! DataAvailable ) + { + return STATUS_TIMEOUT; + } + + /* Data is available - wait for the "DSP ready" code */ + while ( (QuerySystemTimeMs() < Expiry) || ( Timeout == 0) ) + { if ( READ_SB_DSP_DATA(BasePort) == SB_DSP_READY ) { - return TRUE; - } - } - - return FALSE; -} - -BOOLEAN -WaitForSoundBlasterDSPReady( + return STATUS_SUCCESS; + } + } + + return STATUS_TIMEOUT; +} + +NTSTATUS +SbDspWaitToWrite( IN PUCHAR BasePort, IN ULONG Timeout) { @@ -57,19 +72,228 @@
while ( (QuerySystemTimeMs() < Expiry) || (Timeout == 0) ) { - // ... - } - - return FALSE; -} - -NTSTATUS -GetSoundBlasterDSPVersion( + if ( SB_DSP_CLEAR_TO_SEND(BasePort) ) + { + return STATUS_SUCCESS; + } + } + + return STATUS_TIMEOUT; +} + +NTSTATUS +SbDspWaitToRead( + IN PUCHAR BasePort, + IN ULONG Timeout) +{ + ULONG Expiry = QuerySystemTimeMs() + Timeout; + + while ( (QuerySystemTimeMs() < Expiry) || (Timeout == 0) ) + { + if ( SB_DSP_DATA_AVAILABLE(BasePort) ) + { + return STATUS_SUCCESS; + } + } + + return STATUS_TIMEOUT; +} + +NTSTATUS +SbDspWrite( + IN PUCHAR BasePort, + IN UCHAR DataByte, + IN ULONG Timeout) +{ + NTSTATUS Status; + + Status = SbDspWaitToWrite(BasePort, Timeout); + + if ( ! NT_SUCCESS(Status) ) + { + return Status; + } + + DbgPrint("SBDSP - Writing %02x\n", DataByte); + WRITE_SB_DSP_DATA(BasePort, DataByte); + + return STATUS_SUCCESS; +} + +NTSTATUS +SbDspRead( + IN PUCHAR BasePort, + OUT PUCHAR DataByte, + IN ULONG Timeout) +{ + NTSTATUS Status; + + if ( ! DataByte ) + { + return STATUS_INVALID_PARAMETER_2; + } + + Status = SbDspWaitToRead(BasePort, Timeout); + + if ( ! NT_SUCCESS(Status) ) + { + return Status; + } + + *DataByte = READ_SB_DSP_DATA(BasePort); + DbgPrint("SBDSP - Read %02x\n", *DataByte); + + return STATUS_SUCCESS; +} + +NTSTATUS +SbDspGetVersion( IN PUCHAR BasePort, OUT PUCHAR MajorVersion, OUT PUCHAR MinorVersion, IN ULONG Timeout) { - /* TODO */ - return STATUS_NOT_SUPPORTED; -} + NTSTATUS Status; + + /* Make sure our parameters are sane */ + if ( ! MajorVersion ) + return STATUS_INVALID_PARAMETER_2; + + if ( ! MinorVersion ) + return STATUS_INVALID_PARAMETER_3; + + /* Send version request */ + Status = SbDspWrite(BasePort, SB_DSP_VERSION, Timeout); + if ( ! NT_SUCCESS(Status) ) + return Status; + + /* Get the major version */ + Status = SbDspRead(BasePort, MajorVersion, Timeout); + if ( ! NT_SUCCESS(Status) ) + return FALSE; + + /* Get the minor version */ + Status = SbDspRead(BasePort, MinorVersion, Timeout); + return Status; +} + +NTSTATUS +SbDspEnableSpeaker( + IN PUCHAR BasePort, + IN ULONG Timeout) +{ + return SbDspWrite(BasePort, SB_DSP_SPEAKER_ON, Timeout); +} + +NTSTATUS +SbDspDisableSpeaker( + IN PUCHAR BasePort, + IN ULONG Timeout) +{ + return SbDspWrite(BasePort, SB_DSP_SPEAKER_OFF, Timeout); +} + +/* + BUG? + It seems under VirtualBox this returns 0x05, irrespective + of the speaker state. I'm not sure if this will also occur + on real hardware. +*/ +NTSTATUS +SbDspIsSpeakerEnabled( + IN PUCHAR BasePort, + OUT PBOOLEAN IsEnabled, + IN ULONG Timeout) +{ + NTSTATUS Status; + UCHAR SpeakerStatus = 0; + + if ( ! IsEnabled ) + return STATUS_INVALID_PARAMETER_2; + + /* Request the speaker status */ + Status = SbDspWrite(BasePort, SB_DSP_SPEAKER_STATUS, Timeout); + if ( ! NT_SUCCESS(Status) ) + return Status; + + /* Obtain the status */ + Status = SbDspRead(BasePort, &SpeakerStatus, Timeout); + if ( ! NT_SUCCESS(Status) ) + return Status; + + DbgPrint("SBDSP - SpeakerStatus is %02x\n", SpeakerStatus); + *IsEnabled = (SpeakerStatus == 0xFF); + + return STATUS_SUCCESS; +} + +BOOLEAN +SbDspIsValidRate( + IN USHORT Rate) +{ + /* Not sure if this range is 100% correct */ + return ( ( Rate >= 5000 ) && ( Rate <= 45000 ) ); +} + +/* Internal routine - call only after submitting one of the rate commands */ +NTSTATUS +SbDspWriteRate( + IN PUCHAR BasePort, + IN USHORT Rate, + IN ULONG Timeout) +{ + NTSTATUS Status; + + if ( ! SbDspIsValidRate(Rate) ) + return STATUS_INVALID_PARAMETER_2; + + /* Write high byte */ + Status = SbDspWrite(BasePort, (Rate & 0xff00) >> 8, Timeout); + if ( ! NT_SUCCESS(Status) ) + return Status; + + /* Write low byte */ + Status = SbDspWrite(BasePort, Rate & 0xff, Timeout); + if ( ! NT_SUCCESS(Status) ) + return Status; + + return Status; +} + +NTSTATUS +SbDspSetOutputRate( + IN PUCHAR BasePort, + IN USHORT Rate, + IN ULONG Timeout) +{ + NTSTATUS Status; + + if ( ! SbDspIsValidRate(Rate) ) + return STATUS_INVALID_PARAMETER_2; + + /* Prepare to write the output rate */ + Status = SbDspWrite(BasePort, SB_DSP_OUTPUT_RATE, (Rate & 0xff00) >> 8); + if ( ! NT_SUCCESS(Status) ) + return Status; + + return SbDspWriteRate(BasePort, Rate, Timeout); +} + +NTSTATUS +SbDspSetInputRate( + IN PUCHAR BasePort, + IN USHORT Rate, + IN ULONG Timeout) +{ + NTSTATUS Status; + + if ( ! SbDspIsValidRate(Rate) ) + return STATUS_INVALID_PARAMETER_2; + + /* Prepare to write the input rate */ + Status = SbDspWrite(BasePort, SB_DSP_OUTPUT_RATE, (Rate & 0xff00) >> 8); + if ( ! NT_SUCCESS(Status) ) + return Status; + + return SbDspWriteRate(BasePort, Rate, Timeout); +}
Modified: branches/silverblade-audio/lib/drivers/sound/time.c URL: http://svn.reactos.org/svn/reactos/branches/silverblade-audio/lib/drivers/so... ============================================================================== --- branches/silverblade-audio/lib/drivers/sound/time.c [iso-8859-1] (original) +++ branches/silverblade-audio/lib/drivers/sound/time.c [iso-8859-1] Tue Jul 1 17:02:54 2008 @@ -3,13 +3,15 @@ Timing helper
Author: - Andrew Greenwood (andrew.greenwood@silverblade.co.uk) + Andrew Greenwood (silverblade@reactos.org)
History: 31 May 2008 - Created
Notes: - Timing may require testing! + Have checked timing in DebugView. A 10,000ms delay covered a period + of 124.305 sec to 134.308 sec. Not 100% accurate but likely down to + the delays in submitting the debug strings? */
/*