Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.

This commit is contained in:
Colin Finck 2017-10-03 07:45:34 +00:00
parent b94e2d8ca0
commit c2c66aff7d
24198 changed files with 0 additions and 37285 deletions

View file

@ -0,0 +1,69 @@
/*
Sound card operations
http://www.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html
*/
#include <ntddk.h>
#include "sndblst.h"
VOID SetOutputSampleRate(ULONG BasePort, ULONG SampleRate)
{
// This only works for DSP v4.xx ONLY - need a workaround!
DPRINT("Setting output sample rate\n");
// WAIT
// if (! WaitToSend(BasePort))
// return;
SB_WRITE_BYTE(BasePort, SB_SET_OUTPUT_RATE);
SB_WRITE_BYTE(BasePort, SampleRate / 256); // high
SB_WRITE_BYTE(BasePort, SampleRate % 256); // low
}
VOID EnableSpeaker(ULONG BasePort, BOOLEAN SpeakerOn)
{
DPRINT("Setting speaker status %d\n", SpeakerOn);
// if (! WaitForWrite(BasePort))
// return;
SB_WRITE_BYTE(BasePort, SpeakerOn ? SB_ENABLE_SPEAKER : SB_DISABLE_SPEAKER);
}
BOOLEAN IsSpeakerEnabled(ULONG BasePort)
{
DPRINT("Obtaining speaker status\n");
// if (! WaitToSend(BasePort))
// return FALSE;
SB_WRITE_BYTE(BasePort, SB_GET_SPEAKER_STATUS);
if (! WaitToReceive(BasePort))
return FALSE;
return SB_READ_DATA(BasePort) == 0xff;
}
VOID BeginPlayback(ULONG BasePort, ULONG BitDepth, ULONG Channels, ULONG BlockSize)
{
DPRINT("BeginPlayback(%d, %d, %d, %d)\n", BasePort, BitDepth, Channels, BlockSize);
// switch(BitDepth)
// {
// case 8 : Command = 0xc0; break;
// case 16 : Command = 0xb0; break; // Make sure we support it
// default : Command = 0xc0;
// }
DPRINT("Initiating playback\n");
// TEMPORARY:
SB_WRITE_BYTE(BasePort, 0xc6);
SB_WRITE_BYTE(BasePort, 0); // mode - TEMPORARY
SB_WRITE_BYTE(BasePort, BlockSize % 256);
SB_WRITE_BYTE(BasePort, BlockSize / 256);
}

View file

@ -0,0 +1,203 @@
/*
Routines to simplify the use of DMA for Sound Blaster driver
*/
#include <ntddk.h>
#include "sndblst.h"
#if 0
BOOLEAN CheckDMA(PDEVICE_EXTENSION Device)
{
// Don't forget to check for Compaq machines (they can't be configured
// manually...)
return TRUE; // for now...
// if (! CompaqBA)
// return (BOOLEAN) !((INPORT(pHw, BOARD_ID) & 0x80) && Device->DMA == 0);
// else
// {
// UCHAR CompaqPIDR;
// UCHAR Expected = (UCHAR)(Device->DMA == 0 ? 0x40 :
// Device->DMA == 1 ? 0x80 :
// 0xc0);
// CompaqPIDR = READ_PORT_UCHAR(pHw->CompaqBA + BOARD_ID);
// if (CompaqPIDR != 0xff)
// {
// if ((UCHAR)(CompaqPIDR & 0xc0) == Expected)
// return true;
// }
// }
return FALSE;
}
#endif
static IO_ALLOCATION_ACTION NTAPI SoundProgramDMA(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID MapRegisterBase,
IN PVOID Context)
{
PDEVICE_EXTENSION Device = DeviceObject->DeviceExtension;
ULONG zzz;
PUCHAR VirtualAddress = (PUCHAR) MmGetMdlVirtualAddress(Device->Mdl);
DPRINT("IoMapTransfer\n");
IoMapTransfer(Device->Adapter,
Device->Mdl,
MapRegisterBase,
(PUCHAR) MmGetMdlVirtualAddress(Device->Mdl),
&Device->BufferSize, // is this right?
TRUE);
DPRINT("VBuffer == 0x%x (really 0x%x?) Bufsize == %u\n", Device->VirtualBuffer, MmGetPhysicalAddress(Device->VirtualBuffer), Device->BufferSize);
DPRINT("Writing %u bytes of garbage...\n", Device->BufferSize);
// Write some garbage:
for (zzz = 0; zzz < Device->BufferSize; zzz ++)
*(VirtualAddress + zzz) = (UCHAR) zzz % 200;
DPRINT("done\n");
KeSetEvent(Context, 0, FALSE);
return KeepObject;
}
BOOLEAN CreateDMA(PDEVICE_OBJECT DeviceObject)
{
DEVICE_DESCRIPTION Desc;
ULONG MappedRegs = 0;
PDEVICE_EXTENSION Device = DeviceObject->DeviceExtension;
KEVENT DMAEvent;
KIRQL OldIrql;
// Buffersize should already be set but it isn't yet !
Device->BufferSize = SB_BUFSIZE;
DPRINT("Bufsize == %u\n", Device->BufferSize);
RtlZeroMemory(&Desc, sizeof(DEVICE_DESCRIPTION));
// Init memory!
Desc.Version = DEVICE_DESCRIPTION_VERSION;
Desc.Master = FALSE; // Slave
Desc.ScatterGather = FALSE; // Don't think so anyway
Desc.DemandMode = FALSE; // == !SingleModeDMA
Desc.AutoInitialize = TRUE; // ?
Desc.Dma32BitAddresses = FALSE; // I don't think we can
Desc.IgnoreCount = FALSE; // Should be OK
Desc.Reserved1 = 0;
// Desc.Reserved2 = 0;
Desc.BusNumber = 0;
Desc.DmaChannel = Device->DMA; // Our channel :)
Desc.InterfaceType = Isa; // (BusType == MicroChannel) ? MicroChannel : Isa;
Desc.DmaWidth = 0; // hmm... 8 bits?
Desc.DmaSpeed = 0; // double hmm (Compatible it should be)
Desc.MaximumLength = Device->BufferSize;
// Desc.MinimumLength = 0;
Desc.DmaPort = 0;
DPRINT("Calling HalGetAdapter(), asking for %d mapped regs\n", MappedRegs);
Device->Adapter = HalGetAdapter(&Desc, &MappedRegs);
DPRINT("Called\n");
if (! Device->Adapter)
{
DPRINT("HalGetAdapter() FAILED\n");
return FALSE;
}
DPRINT("Bufsize == %u\n", Device->BufferSize);
if (MappedRegs < BYTES_TO_PAGES(Device->BufferSize))
{
DPRINT("Could only allocate %u mapping registers\n", MappedRegs);
if (MappedRegs == 0)
return FALSE;
Device->BufferSize = MappedRegs * PAGE_SIZE;
DPRINT("Bufsize == %u\n", Device->BufferSize);
}
DPRINT("Allocated %u mapping registers\n", MappedRegs);
// Check if we already have memory here...
// Check to make sure we're >= minimum
DPRINT("Allocating buffer\n");
DPRINT("Bufsize == %u\n", Device->BufferSize);
Device->VirtualBuffer = HalAllocateCommonBuffer(Device->Adapter, Device->BufferSize,
&Device->Buffer, FALSE);
// For some reason BufferSize == 0 here?!
// DPRINT("Buffer == 0x%x Bufsize == %u\n", Device->Buffer, Device->BufferSize);
DPRINT("Bufsize == %u,", Device->BufferSize);
DPRINT("Buffer == 0x%x\n", Device->Buffer);
if (! Device->VirtualBuffer)
{
DPRINT("Could not allocate buffer :(\n");
// should try again with smaller buffer...
return FALSE;
}
// DPRINT("Buffer == 0x%x Bufsize == %u\n", Device->Buffer, Device->BufferSize);
DPRINT("Bufsize == %u,", Device->BufferSize);
DPRINT("Buffer == 0x%x\n", Device->Buffer);
DPRINT("Calling IoAllocateMdl()\n");
Device->Mdl = IoAllocateMdl(Device->VirtualBuffer, Device->BufferSize, FALSE, FALSE, NULL);
DPRINT("Bufsize == %u\n", Device->BufferSize);
// IS THIS RIGHT:
if (! Device->Mdl)
{
DPRINT("IoAllocateMdl() FAILED\n");
// Free the HAL buffer
return FALSE;
}
DPRINT("VBuffer == 0x%x Mdl == %u Bufsize == %u\n", Device->VirtualBuffer, Device->Mdl, Device->BufferSize);
DPRINT("Calling MmBuildMdlForNonPagedPool\n");
MmBuildMdlForNonPagedPool(Device->Mdl);
DPRINT("Bufsize == %u\n", Device->BufferSize);
// part II:
KeInitializeEvent(&DMAEvent, SynchronizationEvent, FALSE);
// Raise IRQL
KeRaiseIrql(DISPATCH_LEVEL,&OldIrql);
IoAllocateAdapterChannel(Device->Adapter, DeviceObject,
BYTES_TO_PAGES(Device->BufferSize),
SoundProgramDMA, &DMAEvent);
// Lower IRQL
KeLowerIrql(OldIrql);
DPRINT("VBuffer == 0x%x Bufsize == %u\n", Device->VirtualBuffer, Device->BufferSize);
KeWaitForSingleObject(&DMAEvent, Executive, KernelMode, FALSE, NULL);
// if (MappedRegs == 0)
// MappedRegs = 2;
// else
// MappedRegs ++;
// Status = IoAllocateAdapterChannel(
// Adapter,
// DeviceObject,
// MappedRegs,
// CALLBACK,
// DeviceObject); // Context
return TRUE;
}

View file

@ -0,0 +1,93 @@
#include <ntddk.h>
#include "sndblst.h"
#if 0
BOOLEAN CheckIRQ(PDEVICE_EXTENSION Parameters)
{
static CONST ULONG ValidIRQs[] = VALID_IRQS;
int i;
return TRUE; // for now...
// Check for Compaq!
// if ...
for (i = 0; ValidIRQs[i] != 0xffff; i ++)
{
// Consult the card
// OUTPORT(pHw, BOARD_CONFIG, bConfig);
// if (INPORT(pHEW, BOARD_ID) & 0x40)
// pHW->ValidInterrupts |= (1 << ThisIRQ);
// return (BOOLEAN)((pHw->ValidInterrupts & (1 << Interrupt)) &&
// (! ((INPORT(pHw, BOARD_ID) & 0x80) &&
// (Interrupt == 10 || Interrupt == 11)));
}
// else
// Compaq stuff?
{
UCHAR Expected;
switch (Parameters->IRQ)
{
case 10 : Expected = 0x10;
case 11 : Expected = 0x20;
case 7 : Expected = 0x30;
default : return FALSE;
}
// CompaqPIDR = READ_PORT_UCHAR( ... )
// ...
}
}
BOOLEAN ISR(
IN PKINTERRUPT pInterrupt,
IN PVOID Context)
{
DPRINT("*** Processing ISR ***\n");
// What do we do here then?
return FALSE;
}
NTSTATUS EnableIRQ(PDEVICE_OBJECT DeviceObject)
{
PDEVICE_EXTENSION Parameters = DeviceObject->DeviceExtension;
ULONG Vector;
KIRQL IRQ_Level;
KAFFINITY Affinity;
NTSTATUS Status = STATUS_SUCCESS;
Vector = HalGetInterruptVector(Isa, // FIX THIS
0, // FIX THIS
Parameters->IRQ,
Parameters->IRQ,
&IRQ_Level,
&Affinity);
// Status = IoConnectInterrupt(Parameters->Interrupt, // Object
// ISR, // Function
// DeviceObject, // Context
// (PKSPIN_LOCK) NULL,
// Vector,
// IRQ_Level,
// IRQ_Level,
// mode - Latched or Level sensitive?
// share - if irq can be shared
// Affinity,
// FALSE);
return Status == STATUS_INVALID_PARAMETER ?
STATUS_DEVICE_CONFIGURATION_ERROR : Status;
}
#endif

View file

@ -0,0 +1,111 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/dd/sndblst/portio.c (see also sndblst.h)
* PURPOSE: Sound Blaster port I/O helper
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Sept 28, 2003: Created
*/
#include <ntddk.h>
#include "sndblst.h"
BOOLEAN WaitToSend(ULONG BasePort)
{
int TimeOut;
DPRINT("WaitToSend ");
// Check if it's OK to send
for (TimeOut = SB_TIMEOUT;
! SB_READY_TO_SEND(BasePort) && TimeOut > 0;
TimeOut --);
// If a time-out occurs, we report failure
if (! TimeOut)
{
DPRINT("FAILED\n");
return FALSE;
}
DPRINT("SUCCEEDED\n");
return TRUE;
}
BOOLEAN WaitToReceive(ULONG BasePort)
{
int TimeOut;
DPRINT("WaitToReceive ");
// Check if it's OK to receive
for (TimeOut = SB_TIMEOUT;
! SB_READY_TO_RECEIVE(BasePort) && TimeOut > 0;
TimeOut --);
// If a time-out occurs, we report failure
if (! TimeOut)
{
DPRINT("FAILED\n");
return FALSE;
}
DPRINT("SUCCEEDED\n");
return TRUE;
}
USHORT InitSoundCard(ULONG BasePort)
{
ULONG TimeOut;
BOOLEAN Status;
UCHAR DSP_Major, DSP_Minor;
DPRINT("InitSoundCard() called\n");
DPRINT("Resetting sound card\n");
// if (!WaitToSend(BasePort))
// return FALSE;
SB_WRITE_RESET(BasePort, 0x01);
for (TimeOut = 0; TimeOut < 30000; TimeOut ++); // Wait a while
SB_WRITE_RESET(BasePort, 0x00);
// Check if it's OK to receive (some cards will ignore the above reset
// command and so will not issue an ACK, so time out is NOT an error)
DPRINT("Waiting for an ACK\n");
if (WaitToReceive(BasePort))
{
// Check to make sure the reset was acknowledged:
for (TimeOut = SB_TIMEOUT;
(Status = (SB_READ_DATA(BasePort) != SB_DSP_READY) && (TimeOut > 0));
TimeOut --);
}
DPRINT("Querying DSP version\n");
if (! WaitToSend(BasePort))
return FALSE;
SB_WRITE_DATA(BasePort, SB_GET_DSP_VERSION);
if (! WaitToReceive(BasePort))
return FALSE;
DSP_Major = SB_READ_DATA(BasePort);
DSP_Minor = SB_READ_DATA(BasePort);
DPRINT("DSP v%d.%d\n", DSP_Major, DSP_Minor);
// if audio is disabled,
// version tests return 0xFF everywhere
if (DSP_Major == 0xFF && DSP_Minor == 0xFF)
return FALSE;
DPRINT("Sound card initialized!\n");
return (DSP_Major * 256) + DSP_Minor;
}

View file

@ -0,0 +1,24 @@
#ifndef NDEBUG
#define TEST_STATUS(s) \
if (! NT_SUCCESS(s)) \
{ \
if (s == STATUS_NO_MORE_ENTRIES) \
DPRINT("NTSTATUS == NO MORE ENTRIES\n"); \
else if (s == STATUS_BUFFER_OVERFLOW) \
DPRINT("NTSTATUS == BUFFER OVERFLOW\n"); \
else if (s == STATUS_BUFFER_TOO_SMALL) \
DPRINT("NTSTATUS == BUFFER TOO SMALL\n"); \
else if (s == STATUS_INVALID_PARAMETER) \
DPRINT("NTSTATUS == INVALID PARAMETER\n"); \
else if (s == STATUS_OBJECT_NAME_NOT_FOUND) \
DPRINT("NTSTATUS == OBJECT NAME NOT FOUND\n"); \
else if (s == STATUS_INVALID_HANDLE) \
DPRINT("NTATATUS == INVALID_HANDLE\n"); \
else if (s == STATUS_ACCESS_DENIED) \
DPRINT("NTSTATUS == ACCESS_DENIED\n"); \
else \
DPRINT("NTSTATUS == FAILURE (Unknown)\n"); \
}
#else
#define TEST_STATUS(s)
#endif

View file

@ -0,0 +1,301 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/dd/sndblst/settings.c
* PURPOSE: MPU-401 MIDI device driver setting management
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Sept 28, 2003: Created
*/
#include <ntddk.h>
#include "sndblst.h"
#include "sbdebug.h" // our own debug helper
#if 0
NTSTATUS
OpenDevicesKey(
IN PWSTR RegistryPath,
OUT PHANDLE Key)
/*
Description:
Create a volatile key under this driver's Services node to contain
the device name list.
Parameters:
RegistryPath The location of the registry entry
Key The key in the registry
Return Value:
NT status STATUS_SUCCESS if successful (duh...)
*/
{
NTSTATUS s;
HANDLE hKey;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uStr;
// Attempt to open the key
RtlInitUnicodeString(&uStr, RegistryPath);
InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, NULL,
(PSECURITY_DESCRIPTOR)NULL);
s = ZwOpenKey(&hKey, KEY_CREATE_SUB_KEY, &oa);
if (! NT_SUCCESS(s))
return s; // Problem
// Now create sub key
RtlInitUnicodeString(&uStr, (PWSTR) DEVICE_SUBKEY);
InitializeObjectAttributes(&oa, &uStr, OBJ_CASE_INSENSITIVE, hKey,
(PSECURITY_DESCRIPTOR)NULL);
s = ZwCreateKey(Key, KEY_ALL_ACCESS, &oa, 0, NULL, REG_OPTION_VOLATILE,
NULL);
ZwClose(hKey);
return s;
}
#endif
NTSTATUS NTAPI EnumDeviceKeys(
IN PUNICODE_STRING RegistryPath,
IN PWSTR SubKey,
IN PREGISTRY_CALLBACK_ROUTINE Callback,
IN PVOID Context)
/*
Description:
Enumerate the device subkeys in the driver's registry entry, and
call the specified callback routine for each device.
Parameters:
RegistryPath The location of the registry entry
Subkey The device's subkey
Callback A routine called for each device
Context ???
Return Value:
NT status STATUS_SUCCESS if successful
*/
{
NTSTATUS s;
OBJECT_ATTRIBUTES oa;
HANDLE hKey, hSubKey;
UNICODE_STRING SubkeyName;
ULONG i;
// Attempt to open the key
InitializeObjectAttributes(&oa, RegistryPath, OBJ_CASE_INSENSITIVE,
NULL, (PSECURITY_DESCRIPTOR)NULL);
s = ZwOpenKey(&hKey, KEY_READ, &oa);
TEST_STATUS(s); // debugging
if (! NT_SUCCESS(s))
return s; // Problem
RtlInitUnicodeString(&SubkeyName, SubKey);
DPRINT("Subkey: %wZ\n", &SubkeyName);
InitializeObjectAttributes(&oa, &SubkeyName, OBJ_CASE_INSENSITIVE,
hKey, (PSECURITY_DESCRIPTOR)NULL);
s = ZwOpenKey(&hSubKey, KEY_ENUMERATE_SUB_KEYS, &oa);
ZwClose(hKey);
TEST_STATUS(s); // debugging
if (! NT_SUCCESS(s))
return s;
// And now, the enumeration
for (i = 0;; i ++)
{
KEY_BASIC_INFORMATION Info;
PKEY_BASIC_INFORMATION pInfo;
ULONG ResultLength = 0;
ULONG Size = 0;
PWSTR Pos;
PWSTR Name;
// Find the length of the subkey data
// Info.NameLength = 0; // TEMPORARY!
s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, &Info,
sizeof(Info), &ResultLength);
if (s == STATUS_NO_MORE_ENTRIES)
break;
DPRINT("Found an entry, allocating memory...\n");
// Size = Info.NameLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
Size = ResultLength + FIELD_OFFSET(KEY_BASIC_INFORMATION, Name[0]);
DPRINT("Size is %d\n", Size);
pInfo = (PKEY_BASIC_INFORMATION) ExAllocatePool(PagedPool, Size);
if (pInfo == NULL)
{
DPRINT("INSUFFICIENT RESOURCES!\n");
s = STATUS_INSUFFICIENT_RESOURCES;
break;
}
DPRINT("Re-enumerating...\n");
s = ZwEnumerateKey(hSubKey, i, KeyBasicInformation, pInfo, Size,
&ResultLength);
// TEST_STATUS(s); // debugging
if (! NT_SUCCESS(s))
{
ExFreePool((PVOID) pInfo);
s = STATUS_INTERNAL_ERROR;
break;
}
DPRINT("Allocating memory for name...\n");
Name = ExAllocatePool(PagedPool,
RegistryPath->Length + sizeof(WCHAR) +
SubkeyName.Length + sizeof(WCHAR) +
pInfo->NameLength + sizeof(UNICODE_NULL));
if (Name == NULL)
{
DPRINT("INSUFFICIENT RESOURCES!");
ExFreePool((PVOID) pInfo);
return STATUS_INSUFFICIENT_RESOURCES;
}
// Copy the key name
RtlCopyMemory((PVOID)Name, (PVOID)RegistryPath->Buffer, RegistryPath->Length);
Pos = Name + (RegistryPath->Length / sizeof(WCHAR));
Pos[0] = '\\';
Pos++;
// Copy the parameters sub key name
RtlCopyMemory((PVOID)Pos, (PVOID)SubKey, SubkeyName.Length); //SubkeyName?
Pos += SubkeyName.Length / sizeof(WCHAR);
Pos[0] = '\\';
Pos ++;
// Copy the device sub key name
RtlCopyMemory((PVOID)Pos, (PVOID)pInfo->Name, pInfo->NameLength);
Pos += pInfo->NameLength / sizeof(WCHAR);
Pos[0] = UNICODE_NULL;
ExFreePool((PVOID)pInfo);
DPRINT("Calling callback...\n");
s = (*Callback)(Name, Context);
if (! NT_SUCCESS(s))
{ DPRINT("Callback FAILED\n");
break;}
}
ZwClose(hSubKey);
DPRINT("%d device registry keys found\n", i);
if ((i == 0) && (s == STATUS_NO_MORE_ENTRIES))
return STATUS_DEVICE_CONFIGURATION_ERROR;
return s == STATUS_NO_MORE_ENTRIES ? STATUS_SUCCESS : s;
}
NTSTATUS NTAPI LoadSettings(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext)
/*
Description:
Read the settings for a particular device
Parameters:
ValueName The value to read from the registry
ValueType ?
ValueData ?
ValueLength ?
Context The configuration structure to write to
EntryContext ?
Return Value:
NT status STATUS_SUCCESS if successful
*/
{
PDEVICE_EXTENSION DeviceInfo = Context;
if (ValueType == REG_DWORD)
{
if (! _wcsicmp(ValueName, REGISTRY_PORT))
{
DeviceInfo->Port = *(PULONG) ValueData;
DPRINT("Registry port = 0x%x\n", DeviceInfo->Port);
}
// More to come... (config.c)
}
else
{
// ?
}
return STATUS_SUCCESS;
}
#if 0
NTSTATUS SaveSettings(
IN PWSTR RegistryPath,
IN ULONG Port,
IN ULONG IRQ,
IN ULONG DMA)
/*
Description:
Saves the settings for a particular device
Parameters:
RegistryPath Where to save the settings to
Port The device's port number
IRQ The device's interrupt number
DMA The device's DMA channel
Return Value:
NT status STATUS_SUCCESS if successful
*/
{
DPRINT("SaveSettings() unimplemented\n");
// UNIMPLEMENTED;
return STATUS_SUCCESS;
}
#endif

View file

@ -0,0 +1,468 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/dd/sndblst/sndblst.c
* PURPOSE: Sound Blaster / SB Pro / SB 16 driver
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Sept 28, 2003: Copied from mpu401.c as a template
*/
/* INCLUDES ****************************************************************/
#include <ntddk.h>
#include "sndblst.h"
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath);
/* INTERNAL VARIABLES ******************************************************/
ULONG DeviceCount = 0;
/* FUNCTIONS ***************************************************************/
static NTSTATUS InitDevice(
IN PWSTR RegistryPath,
IN PVOID Context)
{
// PDEVICE_INSTANCE Instance = Context;
PDEVICE_OBJECT DeviceObject; // = Context;
PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\WaveOut0"); // CHANGE THESE?
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\WaveOut0");
// CONFIG Config;
RTL_QUERY_REGISTRY_TABLE Table[2];
NTSTATUS s;
USHORT DSP_Version = 0;
UCHAR DSP_Major = 0, DSP_Minor = 0;
// This is TEMPORARY, to ensure that we don't process more than 1 device.
// This limitation should be removed in future.
if (DeviceCount > 0)
{
DPRINT("Sorry - only 1 device supported by Sound Blaster driver at present :(\n");
return STATUS_NOT_IMPLEMENTED;
}
DPRINT("Creating IO device\n");
s = IoCreateDevice(Context, // driverobject
sizeof(DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_SOUND, // Correct?
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(s))
return s;
DPRINT("Device Extension at 0x%x\n", DeviceObject->DeviceExtension);
Parameters = DeviceObject->DeviceExtension;
DPRINT("Creating DOS link\n");
/* Create the dos device link */
s = IoCreateSymbolicLink(&SymlinkName,
&DeviceName);
if (!NT_SUCCESS(s))
{
IoDeleteDevice(DeviceObject);
return s;
}
DPRINT("Initializing device\n");
// DPRINT("Allocating memory for parameters structure\n");
// Bodged:
// Parameters = (PDEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(DEVICE_EXTENSION));
// DeviceObject->DeviceExtension = Parameters;
// Parameters = Instance->DriverObject->DriverExtension;
DPRINT("DeviceObject at 0x%x, DeviceExtension at 0x%x\n", DeviceObject, Parameters);
if (! Parameters)
{
DPRINT("NULL POINTER!\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
// Instance->DriverObject->DriverExtension = Parameters;
DPRINT("Setting reg path\n");
Parameters->RegistryPath = RegistryPath;
// Parameters->DriverObject = Instance->DriverObject;
DPRINT("Zeroing table memory and setting query routine\n");
RtlZeroMemory(Table, sizeof(Table));
Table[0].QueryRoutine = LoadSettings;
DPRINT("Setting port and IRQ defaults\n");
Parameters->Port = DEFAULT_PORT;
Parameters->IRQ = DEFAULT_IRQ;
Parameters->DMA = DEFAULT_DMA;
Parameters->BufferSize = DEFAULT_BUFSIZE;
// Only to be enabled once we can get support for multiple cards working :)
/*
DPRINT("Loading settings from: %S\n", RegistryPath);
s = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath, Table,
&Parameters, NULL);
if (! NT_SUCCESS(s))
return s;
*/
DPRINT("Port 0x%x IRQ %d DMA %d\n", Parameters->Port, Parameters->IRQ, Parameters->DMA);
// Instance->P
// Initialize the card
DSP_Version = InitSoundCard(Parameters->Port);
if (! DSP_Version)
{
DPRINT("Sound card initialization FAILED!\n");
// Set state indication somehow
// Failure - what error code do we give?!
// return STATUS_????
IoDeleteDevice(DeviceObject);
return STATUS_UNSUCCESSFUL;
}
DSP_Major = DSP_Version / 256;
DSP_Minor = DSP_Version % 256;
// Do stuff related to version here...
DPRINT("Allocating DMA\n");
if (! CreateDMA(DeviceObject))
DPRINT("FAILURE!\n");
// TEMPORARY TESTING STUFF: should be in BlasterCreate
EnableSpeaker(Parameters->Port, TRUE);
SetOutputSampleRate(Parameters->Port, 2205);
BeginPlayback(Parameters->Port, 16, 2, Parameters->BufferSize);
DeviceCount ++;
return STATUS_SUCCESS;
}
static NTSTATUS NTAPI
BlasterCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
DPRINT("BlasterCreate() called!\n");
// Initialize the MPU-401
// ... do stuff ...
// Play a note to say we're alive:
// WaitToSend(MPU401_PORT);
// MPU401_WRITE_DATA(MPU401_PORT, 0x90);
// WaitToSend(MPU401_PORT);
// MPU401_WRITE_DATA(MPU401_PORT, 0x50);
// WaitToSend(MPU401_PORT);
// MPU401_WRITE_DATA(MPU401_PORT, 0x7f);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
DPRINT("IoCompleteRequest()\n");
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
DPRINT("BlasterCreate() completed\n");
return(STATUS_SUCCESS);
}
static NTSTATUS NTAPI
BlasterClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PDEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
DPRINT("BlasterClose() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(Status);
}
static NTSTATUS NTAPI
BlasterCleanup(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
ULONG Channel;
DPRINT("BlasterCleanup() called!\n");
// Reset the device (should we do this?)
for (Channel = 0; Channel <= 15; Channel ++)
{
// All notes off
// MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 123, 0);
// All controllers off
// MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 121, 0);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
static NTSTATUS NTAPI
BlasterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION Stack;
PDEVICE_EXTENSION DeviceExtension;
ULONG ByteCount;
PUCHAR Data;
DPRINT("BlasterWrite() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("%d bytes\n", Stack->Parameters.Write.Length);
Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
for (ByteCount = 0; ByteCount < Stack->Parameters.Write.Length; ByteCount ++)
{
// DPRINT("0x%x ", Data[ByteCount]);
// MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
static NTSTATUS NTAPI
BlasterDeviceControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Handles user mode requests
* ARGUMENTS:
* DeviceObject = Device for request
* Irp = I/O request packet describing request
* RETURNS: Success or failure
*/
{
PIO_STACK_LOCATION Stack;
PDEVICE_EXTENSION DeviceExtension;
DPRINT("BlasterDeviceControl() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
switch(Stack->Parameters.DeviceIoControl.IoControlCode)
{
/* case IOCTL_MIDI_PLAY :
{
DPRINT("Received IOCTL_MIDI_PLAY\n");
Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
DPRINT("Sending %d bytes of MIDI data to 0x%x:\n", Stack->Parameters.DeviceIoControl.InputBufferLength, DeviceExtension->Port);
for (ByteCount = 0; ByteCount < Stack->Parameters.DeviceIoControl.InputBufferLength; ByteCount ++)
{
DPRINT("0x%x ", Data[ByteCount]);
MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
// if (WaitToSend(MPU401_PORT))
// MPU401_WRITE_DATA(MPU401_PORT, Data[ByteCount]);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
*/
}
return(STATUS_SUCCESS);
/*
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
Irp->IoStatus.Information = 0;
if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
{
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_NOT_IMPLEMENTED);
}
if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))
|| (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)
|| (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_INVALID_PARAMETER);
}
DueTime.QuadPart = 0;
*/
/* do the beep!! */
/* DPRINT("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n",
pbsp->Frequency,
pbsp->Duration);
if (BeepParam->Duration >= 0)
{
DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
KeSetTimer(&DeviceExtension->Timer,
DueTime,
&DeviceExtension->Dpc);
HalMakeBeep(BeepParam->Frequency);
DeviceExtension->BeepOn = TRUE;
KeWaitForSingleObject(&DeviceExtension->Event,
Executive,
KernelMode,
FALSE,
NULL);
}
else if (BeepParam->Duration == (DWORD)-1)
{
if (DeviceExtension->BeepOn != FALSE)
{
HalMakeBeep(0);
DeviceExtension->BeepOn = FALSE;
}
else
{
HalMakeBeep(BeepParam->Frequency);
DeviceExtension->BeepOn = TRUE;
}
}
DPRINT("Did the beep!\n");
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,
IO_NO_INCREMENT);
return(STATUS_SUCCESS);
*/
}
static VOID NTAPI
BlasterUnload(PDRIVER_OBJECT DriverObject)
{
DPRINT("BlasterUnload() called!\n");
}
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initialize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
// PDEVICE_EXTENSION DeviceExtension;
// PDEVICE_OBJECT DeviceObject;
// DEVICE_INSTANCE Instance;
// Doesn't support multiple instances (yet ...)
NTSTATUS Status;
DPRINT("Sound Blaster Device Driver 0.0.2\n");
// Instance.DriverObject = DriverObject;
// previous instance = NULL...
// DeviceExtension->RegistryPath = RegistryPath;
DriverObject->Flags = 0;
DriverObject->MajorFunction[IRP_MJ_CREATE] = BlasterCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = BlasterClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BlasterCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BlasterDeviceControl;
DriverObject->MajorFunction[IRP_MJ_WRITE] = BlasterWrite;
DriverObject->DriverUnload = BlasterUnload;
// Major hack to just get this damn thing working:
Status = InitDevice(RegistryPath->Buffer, DriverObject); // ????
// DPRINT("Enumerating devices at %wZ\n", RegistryPath);
// Status = EnumDeviceKeys(RegistryPath, PARMS_SUBKEY, InitDevice, (PVOID)&DeviceObject); // &Instance;
// check error
/* set up device extension */
// DeviceExtension = DeviceObject->DeviceExtension;
// DeviceExtension->BeepOn = FALSE;
// return(STATUS_SUCCESS);
return(Status);
}
/* EOF */

View file

@ -0,0 +1,173 @@
/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/dd/sndblst/sndblst.h
* PURPOSE: Sound Blaster driver header
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Sept 28, 2003: Created
*/
#pragma once
#include <ntddk.h>
#define NDEBUG
#include <debug.h>
#define DEFAULT_PORT 0x220
#define DEFAULT_IRQ 5
#define DEFAULT_DMA 1
#define DEFAULT_BUFSIZE 0x4000
#define DEFAULT_SAMPLERATE 11025
#define DEFAULT_BITDEPTH 8
#define DEFAULT_CHANNELS 1
#define VALID_IRQS {5}
#define MIN_BUFSIZE 0x1000
#define MAX_BUFSIZE 0x4000
#define DEVICE_SUBKEY L"Devices"
#define PARMS_SUBKEY L"Parameters"
#define REGISTRY_PORT L"Port"
// At the moment, we just support a single device with fixed parameters:
#define SB_PORT DEFAULT_PORT
#define SB_IRQ DEFAULT_IRQ
#define SB_DMA DEFAULT_DMA
#define SB_BUFSIZE DEFAULT_BUFSIZE
#define SB_TIMEOUT 1000000
#define IOCTL_SOUND_BASE FILE_DEVICE_SOUND
#define IOCTL_WAVE_BASE 0x0000 // CORRECT?
/* #define IOCTL_MIDI_PLAY CTL_CODE(IOCTL_SOUND_BASE, IOCTL_MIDI_BASE + 0x0006, \
* METHOD_BUFFERED, FILE_WRITE_ACCESS)
*/
// Some constants
#define SB_DSP_READY 0xaa
// Commands (only the ones we use)
#define SB_SET_OUTPUT_RATE 0x41 // DSP v4.xx only
#define SB_SET_INPUT_RATE 0x42 // DSP v4.xx only
#define SB_SET_BLOCK_SIZE 0x48 // DSP v2.00 +
#define SB_ENABLE_SPEAKER 0xd1
#define SB_DISABLE_SPEAKER 0xd3
#define SB_GET_SPEAKER_STATUS 0xd8 // DSP v2.00 +
#define SB_GET_DSP_VERSION 0xe1
// Hmm... These are a weenie bit trickier than MPU401...
#define SB_WRITE_RESET(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0x6, x)
#define SB_READ_DATA(bp) READ_PORT_UCHAR((PUCHAR) bp+0xa)
#define SB_WRITE_DATA(bp, x) WRITE_PORT_UCHAR((PUCHAR) bp+0xc, x)
#define SB_READ_WRITESTATUS(bp) READ_PORT_UCHAR((PUCHAR) bp+0xc)
#define SB_READ_READSTATUS(bp) READ_PORT_UCHAR((PUCHAR) bp+0xe)
// Flow control
#define SB_READY_TO_SEND(bp) \
SB_READ_WRITESTATUS(bp) & 0x80
#define SB_READY_TO_RECEIVE(bp) \
SB_READ_READSTATUS(bp) & 0x80
#define SB_WRITE_BYTE(bp, x) \
if (WaitToSend(bp)) SB_WRITE_DATA(bp, x)
//#define MPU401_READ(bp)
// if (WaitToRead(bp)) ... ???
/*
DEVICE_EXTENSION contains the settings for each individual device
*/
typedef struct _DEVICE_EXTENSION
{
PWSTR RegistryPath;
PDRIVER_OBJECT DriverObject;
ULONG Port;
ULONG IRQ;
ULONG DMA;
ULONG BufferSize;
PADAPTER_OBJECT Adapter;
PMDL Mdl;
PCHAR VirtualBuffer;
PHYSICAL_ADDRESS Buffer;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
/*
DEVICE_INSTANCE contains ???
*/
typedef struct _DEVICE_INSTANCE
{
// pPrevGDI
PDRIVER_OBJECT DriverObject;
} DEVICE_INSTANCE, *PDEVICE_INSTANCE;
/*
CONFIG contains device parameters (port/IRQ)
THIS STRUCTURE IS REDUNDANT
*/
//typedef struct _CONFIG
//{
// ULONG Port;
// ULONG IRQ;
//} CONFIG, *PCONFIG;
/*
Some callback typedefs
*/
typedef NTSTATUS REGISTRY_CALLBACK_ROUTINE(PWSTR RegistryPath, PVOID Context);
typedef REGISTRY_CALLBACK_ROUTINE *PREGISTRY_CALLBACK_ROUTINE;
/*
Prototypes for functions in portio.c :
*/
BOOLEAN WaitToSend(ULONG BasePort);
BOOLEAN WaitToReceive(ULONG BasePort);
USHORT InitSoundCard(ULONG BasePort);
/*
Prototypes for functions in settings.c :
*/
NTSTATUS NTAPI EnumDeviceKeys(
IN PUNICODE_STRING RegistryPath,
IN PWSTR SubKey,
IN PREGISTRY_CALLBACK_ROUTINE Callback,
IN PVOID Context);
NTSTATUS NTAPI LoadSettings(
IN PWSTR ValueName,
IN ULONG ValueType,
IN PVOID ValueData,
IN ULONG ValueLength,
IN PVOID Context,
IN PVOID EntryContext);
BOOLEAN CreateDMA(PDEVICE_OBJECT DeviceObject);
VOID SetOutputSampleRate(ULONG BasePort, ULONG SampleRate);
VOID EnableSpeaker(ULONG BasePort, BOOLEAN SpeakerOn);
BOOLEAN IsSpeakerEnabled(ULONG BasePort);
VOID BeginPlayback(ULONG BasePort, ULONG BitDepth, ULONG Channels, ULONG BlockSize);

View file

@ -0,0 +1,5 @@
#define REACTOS_VERSION_DLL
#define REACTOS_STR_FILE_DESCRIPTION "SoundBlaster Driver"
#define REACTOS_STR_INTERNAL_NAME "sndblst"
#define REACTOS_STR_ORIGINAL_FILENAME "sndblst.sys"
#include <reactos/version.rc>

View file

@ -0,0 +1,70 @@
#include <stdio.h>
#include <windows.h>
#include <ntddk.h>
#include "mpu401.h"
int main()
{
// NTSTATUS s;
// PHANDLE Handle;
// PIO_STATUS_BLOCK Status;
DWORD BytesReturned;
BYTE Test[3]; // Will store MIDI data
BYTE Notes[] = {50, 52, 54, 55, 57, 59, 61};
HANDLE Device;
UINT Note;
UINT Junk;
printf("Test program for MPU401 driver\n");
Device = CreateFile("\\\\.\\MPU401_Out_0", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
NULL);
if (Device == INVALID_HANDLE_VALUE)
{
printf("Device is busy or could not be found.\n");
return -1;
}
printf("Device is open, let's play some music...\n");
Test[0] = 0x90;
Test[2] = 0x7f;
for (Note = 0; Note < sizeof(Notes); Note ++)
{
Test[1] = Notes[Note];
DeviceIoControl(
Device,
IOCTL_MIDI_PLAY,
&Test,
sizeof(Test),
NULL,
0,
&BytesReturned,
NULL
);
for (Junk = 0; Junk < 100000; Junk ++); // Pause
}
/* s = IoCreateFile(Handle, GENERIC_READ | GENERIC_WRITE,
OBJ_KERNEL_HANDLE,
Status,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE,
NULL,
0,
CreateFileTypeNone,
NULL,
0);
*/
}

View file

@ -0,0 +1,54 @@
#include <stdio.h>
#include <windows.h>
#include <ntddk.h>
int main()
{
// NTSTATUS s;
// PHANDLE Handle;
// PIO_STATUS_BLOCK Status;
HANDLE Device;
DWORD BytesReturned;
printf("SB Test\n");
Device = CreateFile("\\\\.\\SndBlst", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING,
NULL);
if (Device == INVALID_HANDLE_VALUE)
{
printf("Device is busy or could not be found.\n");
return -1;
}
// DeviceIoControl(
// Device,
// IOCTL_FILE_DISK_OPEN_FILE,
// OpenFileInformation,
// sizeof(OPEN_FILE_INFORMATION) + OpenFileInformation->FileNameLength - 1,
// NULL
// 0,
// &BytesReturned,
// NULL
// )
/* s = IoCreateFile(Handle, GENERIC_READ | GENERIC_WRITE,
OBJ_KERNEL_HANDLE,
Status,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_NON_DIRECTORY_FILE,
NULL,
0,
CreateFileTypeNone,
NULL,
0);
*/
}