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