1 #pragma once
2 
3 #include <debug.h>
4 #include <ntddk.h>
5 
6 #define SB_WAVE_IN_DEVICE_NAME  L"\\Device\\SBWaveIn"
7 #define SB_WAVE_OUT_DEVICE_NAME L"\\Device\\SBWaveOut"
8 /* TODO: MIDI */
9 #define SB_AUX_DEVICE_NAME      L"\\Device\\SBAux"
10 #define SB_MIXER_DEVICE_NAME    L"\\Device\\SBMixer"
11 
12 #define DEFAULT_PORT        0x220
13 #define DEFAULT_IRQ         5
14 #define DEFAULT_DMA         1
15 #define DEFAULT_BUFFER_SIZE 65535
16 
17 #define SB_TIMEOUT          1000000
18 
19 #define SB_DSP_READY        0xaa
20 
21 enum
22 {
23     NotDetected,
24     SoundBlaster,
25     SoundBlasterPro,
26     SoundBlaster2,
27     SoundBlasterPro2,
28     SoundBlasterProMCV,
29     SoundBlaster16
30 };
31 
32 enum
33 {
34     SB_RESET_PORT           = 0x06,
35     SB_READ_DATA_PORT       = 0x0a,
36     SB_WRITE_DATA_PORT      = 0x0c,
37     SB_WRITE_STATUS_PORT    = 0x0c,
38     SB_READ_STATUS_PORT     = 0x0e
39 };
40 
41 enum
42 {
43     SbAutoInitDmaOutput     = 0x1c,
44     SbAutoInitDmaInput      = 0x2c,
45     SbSetOutputRate         = 0x41, /* DSP v4.xx */
46     SbSetInputRate          = 0x42, /* DSP v4.xx */
47     SbSetBlockSize          = 0x48, /* DSP v2.00 + */
48     SbPauseDac              = 0x80,
49     SbPauseDmaOutput        = 0xd0,
50     SbEnableSpeaker         = 0xd1,
51     SbDisableSpeaker        = 0xd3,
52     SbGetSpeakerStatus      = 0xd8, /* DSP v2.00 + */
53     SbGetDspVersion         = 0xe1
54 };
55 
56 typedef struct _SOUND_BLASTER_PARAMETERS
57 {
58     PDRIVER_OBJECT driver;
59     PWSTR registry_path;
60     PKINTERRUPT interrupt;
61     ULONG port;
62     ULONG irq;
63     ULONG dma;
64     ULONG buffer_size;
65     USHORT dsp_version;
66 } SOUND_BLASTER_PARAMETERS, *PSOUND_BLASTER_PARAMETERS;
67 
68 
69 typedef NTAPI NTSTATUS REGISTRY_CALLBACK_ROUTINE(PDRIVER_OBJECT DriverObject, PWSTR RegistryPath);
70 typedef REGISTRY_CALLBACK_ROUTINE *PREGISTRY_CALLBACK_ROUTINE;
71 
72 
73 /*
74     Port I/O
75 */
76 
77 #define SbWrite(sbdevice, subport, data) \
78     WRITE_PORT_UCHAR((PUCHAR) sbdevice->port + subport, data)
79 
80 #define SbRead(sbdevice, subport) \
81     READ_PORT_UCHAR((PUCHAR) sbdevice->port + subport)
82 
83 #define SbWriteReset(sbdevice, data) \
84     SbWrite(sbdevice, SB_RESET_PORT, data)
85 
86 #define SbWriteDataWithoutWait(sbdevice, data) \
87     SbWrite(sbdevice, SB_WRITE_DATA_PORT, data)
88 
89 #define SbReadDataWithoutWait(sbdevice) \
90     SbRead(sbdevice, SB_READ_DATA_PORT)
91 
92 
93 #define SbGetWriteStatus(sbdevice) \
94     SbRead(sbdevice, SB_WRITE_STATUS_PORT)
95 
96 #define SbGetReadStatus(sbdevice) \
97     SbRead(sbdevice, SB_READ_STATUS_PORT)
98 
99 
100 
101 BOOLEAN
102 WaitForReady(
103     PSOUND_BLASTER_PARAMETERS SBDevice,
104     UCHAR Port);
105 
106 #define WaitToWrite(sbdevice) \
107     WaitForReady(sbdevice, SB_WRITE_STATUS_PORT)
108 
109 #define WaitToRead(sbdevice) \
110     WaitForReady(sbdevice, SB_READ_STATUS_PORT)
111 
112 BOOLEAN
113 ResetSoundBlaster(
114     PSOUND_BLASTER_PARAMETERS SBDevice);
115 
116 ULONG
117 GetSoundBlasterModel(
118     PSOUND_BLASTER_PARAMETERS SBDevice);
119 
120 BOOLEAN
121 IsSampleRateCompatible(
122     PSOUND_BLASTER_PARAMETERS SBDevice,
123     ULONG SampleRate);
124 
125 BOOLEAN
126 SetOutputSampleRate(
127     PSOUND_BLASTER_PARAMETERS SBDevice,
128     ULONG SampleRate);
129 
130 BOOLEAN
131 EnableSpeaker(
132     PSOUND_BLASTER_PARAMETERS SBDevice);
133 
134 BOOLEAN
135 DisableSpeaker(
136     PSOUND_BLASTER_PARAMETERS SBDevice);
137 
138 BOOLEAN
139 StartSoundOutput(
140     PSOUND_BLASTER_PARAMETERS SBDevice,
141     ULONG BitDepth,
142     ULONG Channels,
143     ULONG BlockSize);
144 
145 
146 /*
147     interrupt.c
148 */
149 
150 NTSTATUS
151 EnableIrq(
152     PDEVICE_OBJECT DeviceObject);
153