source: cmedia/trunk/Drv16/init.cpp@ 354

Last change on this file since 354 was 354, checked in by stevenhl, 17 years ago

Import untested baseline cmedia sources, work products and binaries
Binaries and work products should be deleted from repository.
once new builds are verified to work.

File size: 11.6 KB
Line 
1/* $Id: init.cpp,v 1.6 2001/04/30 21:07:57 sandervl Exp $ */
2
3/* SCCSID = %W% %E% */
4/****************************************************************************
5 * *
6 * Copyright (c) IBM Corporation 1994 - 1997. *
7 * *
8 * The following IBM OS/2 source code is provided to you solely for the *
9 * the purpose of assisting you in your development of OS/2 device drivers. *
10 * You may use this code in accordance with the IBM License Agreement *
11 * provided in the IBM Device Driver Source Kit for OS/2. *
12 * *
13 ****************************************************************************/
14/**@internal %W%
15 * Top level device driver initialization.
16 * @version %I%
17 * @context
18 * Physical DD initialization context: Ring3 with I/O privledge.
19 * Discarded after use.
20 * @notes
21 * Creates resource manager object and uses that RM object to figure out
22 * whether audio hardware is present. If present, RM provides IO resources
23 * to operate hardware. This modules uses that information to create
24 * Audio HW objects and other global data structures.
25 * @history
26 */
27
28#pragma code_seg ("_inittext");
29////#pragma data_seg ("_initdata","endds");
30
31extern "C" { // 16-bit header files are not C++ aware
32#define INCL_NOPMAPI
33#define INCL_DOSMISC
34#include <os2.h>
35#include <audio.h>
36#include <os2mixer.h>
37}
38
39#include <ctype.h>
40#include <string.h>
41#include <devhelp.h>
42#include "strategy.h" // OS/2 DD strategy interface
43#include "header.h" // Device driver header
44#include "parse.h" // Parses DEVICE= command line
45#include "malloc.h" // Heap memory used by this driver
46#include "mpu401.hpp" // Object definition
47#include "fmsynth.hpp" // Object definition
48#include "waudio.hpp" // Object definition
49#include "irq.hpp" // Object definition
50#include "timer.hpp" // Object definition
51#include "stream.hpp" // pStreamList
52#include "rm.hpp" // Object definition
53#include "end.h" // end_of_data, end_of_text()
54#include "sizedefs.h" // HEAP_SIZE
55#include "idc_vdd.h" // VDD interface and Data Structs
56#include <include.h> // Pragmas and more.
57#include <sbversion.h>
58#include "commdbg.h"
59#include <dbgos2.h>
60
61//#include "log.hpp"
62//#include "logmsg.hpp"
63
64
65/*
66#ifndef PCI_VENDOR_ID_CREATIVE
67#define PCI_VENDOR_ID_CREATIVE 0x1102UL
68#endif
69
70#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
71#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002UL
72#endif
73
74#define PCI_ID ((PCI_DEVICE_ID_CREATIVE_EMU10K1<<16UL)|PCI_VENDOR_ID_CREATIVE)
75*/
76
77
78#define PCI_VENDOR_ID_CMEDIA 0x13f6UL
79#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100UL
80#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101UL
81#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111UL
82#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112UL
83
84
85// Attention: use same detection order in CMPCI.C
86static struct { ULONG uID; PCHAR pchName; } arDevList[] =
87{
88 { (PCI_DEVICE_ID_CMEDIA_CM8738B << 16) | PCI_VENDOR_ID_CMEDIA, "CMI8738B" },
89 { (PCI_DEVICE_ID_CMEDIA_CM8738 << 16) | PCI_VENDOR_ID_CMEDIA, "CMI8738" },
90 { (PCI_DEVICE_ID_CMEDIA_CM8338B << 16) | PCI_VENDOR_ID_CMEDIA, "CMI8338B" },
91 { (PCI_DEVICE_ID_CMEDIA_CM8338A << 16) | PCI_VENDOR_ID_CMEDIA, "CMI8338A" },
92 { 0, "" },
93};
94
95
96// Default MIDI timer interval, milliseconds.
97static USHORT MIDI_TimerInterval = 10;
98
99static char szMsgSignon[] = "\r\n"PRODUCT_NAME" MMPM/2 Audio Driver v"PRODUCT_VERSION;
100static char szMsgCopyright[] = "Copyright 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)\r\n"
101 "Copyright 2001-2002 Rdiger Ihle (r.ihle@s-t.de)";
102static char szMsgNotFound[] = "Hardware not detected!";
103static char szMsgAllocResFailed1[] = "Another device driver was granted exclusive access to ";
104static char szMsgAllocResFailed2[] = "\r\nUnable to allocate hardware resources! Aborting...";
105static char szMsgConfig1[] = " configuration: IRQ ";
106static char szMsgConfig2[] = ", IO Port 0x";
107static char szMsgNewLine[] = "\r\n\n";
108static char szPort[] = "IO Port 0x";
109static char szIRQ[] = "IRQ ";
110
111
112//
113// ASCII Z-String used to register for PDD-VDD IDC must
114// Name is copied from header at runtime.
115//
116char szPddName[9] = {0};
117char digit[32] = {0};
118
119ResourceManager* pRM = 0; // Resource manager object.
120
121//
122// Strategy Init
123//
124void StrategyInit(PREQPACKET prp)
125{
126 int i;
127 TIMER *pTimer;
128 LDev_Resources *pResources;
129
130 Device_Help = (PFN) prp->s.init_in.ulDevHlp;
131 prp->s.init_out.usCodeEnd = 0;
132 prp->s.init_out.usDataEnd = 0;
133 prp->usStatus = RPDONE | RPERR | RPGENFAIL;
134
135 /* Initialize Heap. */
136 unsigned uInitSize; // Actual size of Heap following initialization.
137 uInitSize = HeapInit( HEAP_SIZE );
138 if ((HEAP_SIZE-uInitSize) > 64) { // Should get size of request, less some overhead.
139 // ### pError->vLog( HeapInitFailure ); //### Error log 'pError' not yet created.
140 return;
141 }
142 /* Heap initialized. */
143
144
145 // Crate logging facilities. By default, the LOG facility will write
146 // to the serial line and the system trace log.
147// pStatus = new LOG( 253, apszStatusMessage );
148// pError = new LOG( 254, apszErrorMessage );
149// pSoftError = pError;
150// pTrace = new BINARYLOG( 255, apszTraceMessage );
151// pPerfLog = new PERFLOG( 255, apszTraceMessage );
152
153
154 // Initialize global lists.
155 pAudioHWList = new QUEUEHEAD;
156 pStreamList = new QUEUEHEAD;
157 pTimerList = new QUEUEHEAD;
158
159 // Fetch command line parameters.
160 if (!GetParms(prp->s.init_in.szArgs)) {
161// Rudi: ignore bad parameters
162// return;
163 }
164
165 // Now that we've grabbed our cmd line options,
166 // we can start processing stuff that depends on those switches.
167
168 if (fInt3BeforeInit) DebugInt3();
169
170 // If we got a /V (verbose) flag on the DEVICE= command, route messages
171 // to the display.
172 if (fVerbose) {
173 USHORT result;
174
175 DosWrite(1, szMsgSignon, sizeof(szMsgSignon)-1, &result);
176 DosWrite(1, szMsgNewLine, 2, &result);
177 DosWrite(1, szMsgCopyright, sizeof(szMsgCopyright), &result);
178 DosWrite(1, szMsgNewLine, 3, &result);
179 }
180
181 if (szCL_DevName[0] != ' ') // Was a valid device name specified?
182 memcpy(phdr->abName,szCL_DevName,8); // yes, copy it to the dev header
183
184 pRM = new ResourceManager(0); // Create the RM object.
185 if (! pRM) {
186 return;
187 }
188
189 //SvL: Check if SB Live hardware has been detected by the resource manager
190 if( pRM->getState() != rmDriverCreated )
191 {
192hardware_notfound:
193 USHORT result;
194
195 DosWrite(1, szMsgNotFound, sizeof(szMsgNotFound)-1, &result);
196 DosWrite(1, szMsgNewLine, 3, &result);
197 return;
198 }
199
200 for( i = 0;
201 arDevList[i].uID && !pRM->bIsDevDetected(arDevList[i].uID, SEARCH_ID_DEVICEID, TRUE);
202 i++ ) ;
203
204 if( !arDevList[i].uID ) goto hardware_notfound;
205
206
207 // Rudi: detect adapter
208 pResources = pRM->pGetDevResources(arDevList[i].uID, SEARCH_ID_DEVICEID, TRUE, FALSE);
209
210 if ((!pResources) || pResources->isEmpty()) {
211 goto hardware_notfound;
212 }
213
214 if (pRM->getState() == rmAllocFailed) {
215 USHORT result;
216
217 DosWrite(1, szMsgAllocResFailed1, sizeof(szMsgAllocResFailed1)-1, &result);
218
219 switch( pRM->getResourceType() ) {
220 case RS_TYPE_IRQ :
221 strcpy(digit, szIRQ);
222 *DecWordToASCII(digit+sizeof(szIRQ)-1, (USHORT)pResources->uIRQLevel[0], 0) = '\0';
223 break;
224
225 case RS_TYPE_IO :
226 strcpy(digit, szPort);
227 *HexWordToASCII(digit+sizeof(szPort)-1, (USHORT)pResources->uIOBase[0], 0) = '\0';
228 break;
229
230 default:
231 strcpy(digit, "???");
232 }
233
234 DosWrite(1, digit, strlen(digit), &result);
235 DosWrite(1, szMsgAllocResFailed2, sizeof(szMsgAllocResFailed2)-1, &result);
236 DosWrite(1, szMsgNewLine, 3, &result);
237 return;
238 }
239
240 if (fVerbose) {
241 USHORT result;
242
243 DosWrite(1, arDevList[i].pchName, _fstrlen(arDevList[i].pchName), &result);
244 DosWrite(1, szMsgConfig1, sizeof(szMsgConfig1)-1, &result);
245 *DecWordToASCII(digit, (USHORT)pResources->uIRQLevel[0], 0) = '\0';
246 DosWrite(1, digit, strlen(digit), &result);
247
248 DosWrite(1, szMsgConfig2, sizeof(szMsgConfig2)-1, &result);
249 *HexWordToASCII(digit, pResources->uIOBase[0], 0) = '\0';
250 DosWrite(1, digit, strlen(digit), &result);
251
252 DosWrite(1, szMsgNewLine, 3, &result);
253 }
254 delete pResources;
255
256
257 // Rudi: "detect" joystick
258 pResources = pRM->pGetDevResources(arDevList[i].uID, SEARCH_ID_DEVICEID, TRUE, TRUE);
259 if( pResources ) {
260 if (pRM->getState() == rmAllocFailed) {
261 USHORT result;
262
263 DosWrite(1, szMsgAllocResFailed1, sizeof(szMsgAllocResFailed1)-1, &result);
264 strcpy(digit, szPort);
265 *HexWordToASCII(digit+sizeof(szPort)-1, (USHORT)pResources->uIOBase[0], 0) = '\0';
266 DosWrite(1, digit, strlen(digit), &result);
267
268 DosWrite(1, szMsgNewLine, 3, &result);
269 }
270
271 delete pResources;
272 }
273
274
275 // FMSYNTH object, this is the default MIDI device
276 // First create a timer, then the HW object.
277 pTimer = new TIMER(NULL, MIDI_TimerInterval, STREAM_FMSYNTH_PLAY);
278 if (pTimer->eState() != TIMER_Disabled)
279 {
280 new FMSYNTH(0x388, pTimer);
281 SetHardwareType(AUDIOHW_FMSYNTH_PLAY, MIDI, OPERATION_PLAY, 0);
282 SetHardwareType(AUDIOHW_FMSYNTH_PLAY, DATATYPE_MIDI, OPERATION_PLAY, 0);
283// SetHardwareType(AUDIOHW_FMSYNTH_PLAY, DATATYPE_NULL, OPERATION_PLAY, 0);
284 }
285
286#if 0
287 // MPU401 object, this is the secondary MIDI device
288 // First create a timer, then the HW object.
289 pTimer = new TIMER(NULL, MIDI_TimerInterval, STREAM_MPU401_PLAY);
290 if (pTimer->eState() != TIMER_Disabled)
291 {
292 new MPU_401(pTimer);
293 SetHardwareType(AUDIOHW_MPU401_PLAY, MIDI, OPERATION_PLAY, 0);
294 SetHardwareType(AUDIOHW_MPU401_PLAY, DATATYPE_MIDI, OPERATION_PLAY, 0);
295// SetHardwareType(AUDIOHW_MPU401_PLAY, DATATYPE_NULL, OPERATION_PLAY, 0);
296 }
297#endif
298
299 // Build the Wave Playback Hardware object
300 new WAVEAUDIO(AUDIOHW_WAVE_PLAY);
301
302 // Build the Wave Capture Hardware object
303 new WAVEAUDIO(AUDIOHW_WAVE_CAPTURE);
304
305
306#if 0
307 // fill in the ADAPTERINFO
308 codec_info.ulNumPorts = NUMIORANGES;
309 codec_info.Range[0].ulPort = pResourcesWSS->uIOBase[0];
310 codec_info.Range[0].ulRange = pResourcesWSS->uIOLength[0];
311 codec_info.Range[1].ulPort = pResourcesWSS->uIOBase[1];
312 codec_info.Range[1].ulRange = pResourcesWSS->uIOLength[1];
313 codec_info.Range[2].ulPort = pResourcesWSS->uIOBase[2];
314 codec_info.Range[2].ulRange = pResourcesWSS->uIOLength[2];
315 codec_info.Range[3].ulPort = pResourcesICS->uIOBase[0];
316 codec_info.Range[3].ulRange = pResourcesICS->uIOLength[0];
317
318 // set up the addressing to the codec data for the vdd
319 pfcodec_info = (ADAPTERINFO __far *)&codec_info;
320 DevHelp_VirtToLin (SELECTOROF(pfcodec_info), (ULONG)(OFFSETOF(pfcodec_info)),
321 (PLIN)&pLincodec);
322
323 // copy the pdd name out of the header.
324 for (int i = 0; i < sizeof(szPddName)-1 ; i++) {
325 if (phdr->abName[i] <= ' ')
326 break;
327 szPddName[i] = phdr->abName[i];
328 }
329 // register the VDD IDC entry point..
330 DevHelp_RegisterPDD ((NPSZ)szPddName, (PFN)IDCEntry_VDD);
331#endif
332
333 prp->usStatus = RPDONE;
334 prp->s.init_out.usCodeEnd = (USHORT) &end_of_text;
335 prp->s.init_out.usDataEnd = (USHORT) &end_of_heap;
336}
337
338
Note: See TracBrowser for help on using the repository browser.