|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1992 Microsoft Corporation
4:
5: Module Name:
6:
7: pas.c
8:
9: Abstract:
10:
11: This module contains code configuration code MediaVision's Pro audio
12: spectrum. The card is run in Sound Blaster compatibiltiy mode.
13:
14: Support is provided for volume setting and line input and
15: microphone mix level setting.
16:
17: The card is located by searching. No user configuration is supported.
18:
19: Author:
20:
21: Robin Speed (RobinSp) 17-Oct-1992
22:
23: Environment:
24:
25: Kernel mode
26:
27: Revision History:
28:
29: --*/
30:
31: #include <sound.h>
32:
33:
34:
35: //--------------========================---------------------------
36: //---------====< GLOBAL DATA SECTION >====-------------------------
37: //--------------========================---------------------------
38:
39: // The board signature is the first value in the PAS 16 wakeup sequence
40: // BC is the factory default. A board jumpered to recognize the BD signature
41: // will not respond to a BC init command.
42:
43: UCHAR SignatureTable[4]={0xBC,0xBD,0xBE,0xBF};
44:
45:
46:
47: // SEARCH LOCATIONS LISTED IN ORDER OF SEARCH
48:
49: ULONG search_locations[]=
50: {
51: 0x0388,0x0384,0x038C,
52: 0x0288,0x0280,0x0284,0x028C
53: };
54:
55: //
56: // MPU stuff here until we work out what we want
57: //
58:
59: #define MPU_ADDR 0x330
60:
61: #define MPU_IRQ 2
62: #define MPU_EMUL_IRQ EMUL_IRQ_2
63:
64:
65: //
66: // Local routines
67: //
68:
69:
70: BOOLEAN
71: VerifyProHardware(
72: PGLOBAL_DEVICE_INFO pGDI,
73: ULONG port,
74: FOUNDINFO *pFI);
75:
76: BOOLEAN
77: VerifyNothingThere(
78: PGLOBAL_DEVICE_INFO pGDI,
79: ULONG port);
80:
81: BOOLEAN
82: WakeUpAtAddress(
83: PGLOBAL_DEVICE_INFO pGDI,
84: ULONG wPort,
85: FOUNDINFO *pFoundInfo );
86:
87: void
88: InitProHardware(
89: PFOUNDINFO pFI,
90: PSB_CONFIG_DATA ConfigData);
91:
92: void
93: InitMixerState(
94: PFOUNDINFO pFI);
95:
96: NTSTATUS
97: ReportUsage(
98: PGLOBAL_DEVICE_INFO pGDI,
99: ULONG BasePort
100: );
101:
102: #ifdef ALLOC_PRAGMA
103: #pragma alloc_text(init,VerifyProHardware)
104: #pragma alloc_text(init,VerifyNothingThere)
105: #pragma alloc_text(init,WakeUpAtAddress)
106: #pragma alloc_text(init,InitProHardware)
107: #pragma alloc_text(init,InitMixerState)
108: #pragma alloc_text(init,ReportUsage)
109: #pragma alloc_text(init,FindPasHardware)
110: #pragma alloc_text(init,InitPasAndMixer)
111: #endif
112:
113: /****************************************************************************
114: *
115: * Report all the ports used by the PAS assuming it's at a given port
116: * location.
117: *
118: * We report this stuff on the driver object, the sound blaster stuff
119: * gets reported on the wave in device object.
120: *
121: * We don't report the ad lib port here because we don't want to rule
122: * out an ad lib driver loading.
123: *
124: ****************************************************************************/
125:
126: NTSTATUS
127: ReportUsage(
128: PGLOBAL_DEVICE_INFO pGDI,
129: ULONG BasePort
130: )
131: {
132: PCM_RESOURCE_LIST ResList;
133: PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
134: ULONG NumberOfEntries;
135: NTSTATUS Status;
136: BOOLEAN ResourceConflict = FALSE;
137: int i;
138:
139: static ULONG PortList[] = { 0xb88, 0x7f88, 0x8388, 0xf388,
140: 0xf788, 0xff88, 0x4388, 0xbf88 };
141:
142: ULONG Size;
143:
144: Size =
145: FIELD_OFFSET(
146: CM_RESOURCE_LIST,
147: List[0].PartialResourceList.PartialDescriptors[
148: sizeof(PortList) / sizeof(PortList[0]) + 1].Type);
149:
150:
151: //
152: // Create a structure for our reporting
153: //
154:
155: ResList = ExAllocatePool(PagedPool, Size);
156:
157: if (ResList == NULL) {
158: return STATUS_INSUFFICIENT_RESOURCES;
159: }
160:
161: RtlZeroMemory(ResList, Size);
162:
163: //
164: // Copy our reporting data into the resources list
165: //
166:
167: ResList->Count = 1;
168:
169: ResList->List[0].InterfaceType = pGDI->BusType;
170: ResList->List[0].BusNumber = pGDI->BusNumber;
171:
172: ResList->List[0].PartialResourceList.Count =
173: sizeof(PortList) / sizeof(PortList[0]) + 1;
174:
175: Descriptor = ResList->List[0].PartialResourceList.PartialDescriptors;
176:
177:
178: for (i = 0; i < sizeof(PortList) / sizeof(PortList[0]) + 1; i++, Descriptor++) {
179: Descriptor->Type = CmResourceTypePort;
180:
181: Descriptor->ShareDisposition = CmResourceShareDriverExclusive;
182:
183: //
184: // NOTE - because all ports base have the lower 2 bits 0
185: // and all ranges start on an aligned address it is
186: // true that doing the XORing does not affect the start
187: // of the range. This would not in general be true
188: //
189:
190:
191: if (i == 0) {
192: Descriptor->u.Port.Start.LowPart = PAS_2_WAKE_UP_REG;
193:
194: Descriptor->u.Port.Length = 1;
195: } else {
196: Descriptor->u.Port.Start.LowPart =
197: PortList[i - 1] ^ DEFAULT_BASE ^ BasePort;
198:
199: Descriptor->u.Port.Length = 4;
200: }
201: }
202:
203: #if 0
204: if (ReportDMAAndInterrupt) {
205:
206: Descriptor->Type = CmResourceTypeInterrupt;
207:
208: Descriptor->ShareDisposition = CmResourceShareDriverExclusive;
209:
210: Descriptor->Flags =
211: InterruptMode == CM_RESOURCE_INTERRUPT_LATCHED;
212:
213: Descriptor->u.Interrupt.Level = InterruptNumber;
214:
215: Descriptor->u.Interrupt.Vector = InterruptNumber;
216:
217: Descriptor++;
218:
219:
220: Descriptor->Type = CmResourceTypeDma;
221:
222: Descriptor->ShareDisposition = CmResourceShareDeviceExclusive;
223:
224: Descriptor->u.Dma.Channel = DmaChannel;
225:
226: Descriptor->u.Dma.Port = 0; // ???
227: }
228:
229: #endif
230:
231: Status = IoReportResourceUsage(NULL,
232: pGDI->DriverObject,
233: NULL,
234: 0,
235: pGDI->DeviceObject[WaveOutDevice],
236: ResList,
237: Size,
238: FALSE,
239: &ResourceConflict);
240:
241: if (ResourceConflict) {
242: Status = STATUS_DEVICE_CONFIGURATION_ERROR;
243: }
244:
245: ExFreePool(ResList);
246:
247: return Status;
248: }
249:
250:
251:
252: /*\
253: ;---|*|------====< DWORD GetProTableRead() >====------
254: ;---|*|
255: ;---|*| Detects which version of the Pro AudioSpectrum is installed
256: ;---|*|
257: ;---|*| Entry Conditions:
258: ;---|*| Pointer to Profile Structure. If the caller wants to specify
259: ;---|*| the preferred base address for cards not yet init'd, they
260: ;---|*| are passed in this structure. The NumFound field indicates
261: ;---|*| the number of location requests and the board address elements
262: ;---|*| indicate the locations.
263: ;---|*|
264: ;---|*| Also passed in pointer to port (the one we found in the registry
265: ;---|*| if any
266: ;---|*|
267: ;---|*| Exit Conditions:
268: ;---|*| Returns number of cards found
269: ;---|*| ProFile structure has been updated.
270: ;---|*|
271: ; \*/
272:
273:
274: NTSTATUS
275: FindPasHardware(
276: PGLOBAL_DEVICE_INFO pGDI,
277: PSB_CONFIG_DATA ConfigData )
278: {
279: int i;
280: FOUNDINFO *pFoundInfo;
281: ULONG CurrentPort;
282: NTSTATUS Status;
283:
284: // RtlZeroMemory(pPf, sizeof(*pPf)); already 0 on NT
285:
286: //
287: // Get access to all IO ports
288: //
289:
290: pGDI->PASInfo.PROBase =
291: SoundMapPortAddress(pGDI->BusType,
292: pGDI->BusNumber,
293: 0,
294: 0x10000,
295: &pGDI->MemType);
296:
297: //
298: // Check each possible location for a card, starting with the one
299: // we were given (unless it was 0)
300: //
301: for (i=0;
302: i < sizeof(search_locations) / sizeof(search_locations[0]);
303: i++)
304: {
305:
306: CurrentPort = search_locations[i];
307:
308: if (CurrentPort != 0) {
309:
310: //
311: // Check we have access
312: //
313:
314: Status = ReportUsage(pGDI, CurrentPort);
315:
316: if (NT_SUCCESS(Status)) {
317:
318: pFoundInfo=&pGDI->PASInfo;
319:
320: if (VerifyProHardware(pGDI, CurrentPort, pFoundInfo)) {
321:
322: return STATUS_SUCCESS;
323: }
324: } else {
325: if (Status != STATUS_DEVICE_CONFIGURATION_ERROR) {
326: return Status;
327: }
328: }
329: }
330: }
331: //
332: // Finally, we attempt to wake up hardware at default locations unless
333: // we're already found something
334: //
335:
336: if (!pGDI->Hw.ThunderBoard) {
337: for (i=0;
338: i < sizeof(search_locations) / sizeof(search_locations[0]);
339: i++)
340: {
341:
342: CurrentPort = search_locations[i];
343: if (CurrentPort != 0) {
344:
345:
346: pFoundInfo=&pGDI->PASInfo;
347:
348: if ( VerifyNothingThere ( pGDI, CurrentPort ))
349: {
350: //
351: // Check we have access
352: //
353:
354: Status = ReportUsage(pGDI, CurrentPort);
355:
356: if (NT_SUCCESS(Status)) {
357:
358: if (WakeUpAtAddress ( pGDI, CurrentPort, pFoundInfo )) {
359: return STATUS_SUCCESS;
360: } else {
361: //
362: // Must be at the first possible location
363: //
364:
365: return STATUS_DEVICE_CONFIGURATION_ERROR;
366: }
367: } else {
368: if (Status != STATUS_DEVICE_CONFIGURATION_ERROR) {
369: return Status;
370: }
371: }
372: }
373: }
374:
375: }
376: }
377:
378: return STATUS_DEVICE_CONFIGURATION_ERROR;
379: }
380:
381: /*\
382: ;---|*|------====< int VerifyProHardware() >====------
383: ;---|*|
384: ;---|*| Detects which version of the Pro AudioSpectrum is installed
385: ;---|*|
386: ;---|*| Entry Conditions:
387: ;---|*| wParam1= Base I/O address to check
388: ;---|*|
389: ;---|*| Exit Conditions:
390: ;---|*| Returns AX=PORT ADDRESS if Pro AudioSpectrum found
391: ;---|*| Returns AX=NO_PAS_INSTALLED if Pro AudioSpectrum not found
392: ;---|*|
393: ;---|*| WARNING: THIS IS PASCAL TYPE, IT POPS ITS PARAMETERS
394: ; \*/
395:
396:
397: BOOLEAN
398: VerifyProHardware(
399: PGLOBAL_DEVICE_INFO pGDI,
400: ULONG port,
401: FOUNDINFO *pFI)
402: {
403: UCHAR bData, bTemp;
404:
405: pFI->TranslateCode = port ^ DEFAULT_BASE;
406:
407: bData=PASX_IN (pFI, INTERRUPT_CTRL_REG);
408:
409: if (bData==0xFF) // 0xFF usually means nothing there
410: goto VerifyFailed;
411: pFI->wBoardRev= (bData >>5); // board rev is 3 topmost bits
412:
413: switch (pFI->wBoardRev)
414: {
415: case PAS_VERSION_1:
416: //case PAS_PLUS: // same boardrev as PAS_SIXTEEN
417: case PAS_SIXTEEN:
418: case PAS_CDPC:
419: break;
420:
421: default:
422: goto VerifyFailed; // unknown hardware type
423: }
424:
425: PASX_OUT(pFI, INTERRUPT_CTRL_REG, bData ^ 0xE0); // try changing version bits
426: bTemp=PASX_IN (pFI, INTERRUPT_CTRL_REG); // they should be read only
427:
428: if ((bTemp & (D7+D6+D5)) != (bData & (D7+D6+D5))) {
429: PASX_OUT(pFI, INTERRUPT_CTRL_REG, bData); // Excuse me, stranger.
430: goto VerifyFailed;
431: }
432:
433: if (pFI->wBoardRev==PAS_VERSION_1) {
434:
435: pFI->Caps.CapsBits.CDInterfaceType=SCSI_TYPE;
436:
437: //
438: // test for Enhanced SCSI mod (U48)
439: //
440:
441: PASX_OUT(pFI, ENHANCED_SCSI_DETECT_REG, 0 ); // write to try changing version bits
442: KeStallExecutionProcessor(10); // wait 10 us
443: bTemp=PASX_IN ( pFI, ENHANCED_SCSI_DETECT_REG ); // they should be read only
444:
445: switch (bTemp & 1) // bit0==1 means old SCSI PAL
446: {
447: case 0:
448: pFI->Caps.CapsBits.EnhancedSCSI=TRUE;
449: // allow to fall thru
450:
451: case 1:
452: goto ProVerified;
453: }
454: } else {
455: // if PAS hardware installed, the reset bit can never be on
456:
457: bTemp=PASX_IN (pFI, SYSTEM_CONFIG_1); // get PAS config register
458: if (bTemp & D7) // D7 is reset bit
459: goto VerifyFailed;
460:
461:
462: bTemp=PASX_IN (pFI, SLAVE_MODE_READ);
463:
464: if (bTemp & SLAVE_MODE_OPL3)
465: pFI->Caps.CapsBits.OPL_3=TRUE;
466:
467: if (bTemp & SLAVE_MODE_16)
468: {
469: pFI->Caps.CapsBits.DAC16=TRUE;
470: pFI->Caps.CapsBits.DualDAC=TRUE;
471:
472: // if 16-bit DAC, and not a CDPC, it has a 508 chip.
473: // Note: PAS 16 w/ VGA will have Mixer 508 also.
474:
475: if (pFI->wBoardRev != PAS_CDPC)
476: pFI->Caps.CapsBits.Mixer_508=TRUE;
477:
478: }
479:
480: pFI->Caps.CapsBits.CDInterfaceType=(bTemp & (D1+D0));
481:
482: if (pFI->Caps.CapsBits.CDInterfaceType==SCSI_TYPE)
483: pFI->Caps.CapsBits.SCSI_IO_16=TRUE;
484:
485: pFI->Caps.CapsBits.Slot16=TRUE;
486: pFI->Caps.CapsBits.SoundBlaster=TRUE;
487:
488: bTemp=PASX_IN (pFI, MASTER_MODE_READ); // get slave bits
489: if ((bTemp & D0)==0)
490: pFI->Caps.CapsBits.MCA=TRUE;
491:
492: if (bTemp & D2)
493: pFI->Caps.CapsBits.CDPC=TRUE;
494:
495: pFI->wChipRev=PASX_IN (pFI, CHIP_REV);
496:
497: #if 0 // We're not interested in this stuff
498: if (pFI->wChipRev >= CHIP_REV_D)
499: {
500:
501: bData=PASX_IN(pFI, EMULATION_ADDRESS_POINTER );
502: bTemp=PASX_IN(pFI, COMPATIBLE_REGISTER_ENABLE );
503:
504: if (bTemp & MPU_ENABLE_BIT) // MPU emulation Enabled?
505: pFI->MPUPort=0x300 + (bData & 0xf0);
506:
507: if (bTemp & SB_ENABLE_BIT) // SB emulation Enabled?
508: {
509: pFI->SBPort=0x200 + ((bData & 0x0f)<<4);
510: }
511:
512: //
513: // Report back IRQ usage of PAS DAC and CD
514: //
515:
516: bData=PASX_IN(pFI, IO_PORT_CONFIG_3 );
517: pFI->ProIRQ=IRQTable[bData & 0x0f]; // convert to IRQ value
518:
519: pFI->CDIRQ=IRQTable[bData >> 4]; // convert to IRQ value
520:
521: //
522: // Report back DMA usage of PAS
523: //
524:
525: bData=PASX_IN(pFI, IO_PORT_CONFIG_2 );
526: pFI->ProDMA=DMATable[bData & (D2+D1+D0)];
527:
528:
529: // Note: Rev D doesn't allow readback of SB IRQ/DMA pointers
530: // nor the MPU IRQ. The "Set and forget" feature, we
531: // call it.
532:
533: }
534: #endif // We're not interested in this stuff
535:
536: }
537:
538: ProVerified:
539:
540: dprintf2(("Found PRO hardware at %X", port));
541: pFI->ProPort=port; // found at this port
542: return TRUE;
543:
544: ////////////////////////////////
545:
546: VerifyFailed:
547: pFI->wBoardRev=0; // found at this port
548: pFI->Caps.dwCaps=0; // No Board, No Caps
549: return FALSE;
550:
551: }
552:
553: /*\
554: ;---|*|------====< BOOL VerifyNothingThere(port) >====------
555: ;---|*|
556: ;---|*| Tries to determine whether a quadport is vacant
557: ;---|*|
558: ;---|*| Entry Conditions:
559: ;---|*| port= Base I/O address to check
560: ;---|*|
561: ;---|*| Exit Conditions:
562: ;---|*| Returns TRUE if nothing found
563: ;---|*| Returns FALSE if it looks like hardware is there
564: ;---|*|
565: ; \*/
566:
567: BOOLEAN
568: VerifyNothingThere(
569: PGLOBAL_DEVICE_INFO pGDI,
570: ULONG port)
571: {
572: UCHAR b0,b1,b2,b3;
573:
574: //
575: // Check we have access
576: //
577:
578: if (!NT_SUCCESS(SoundReportResourceUsage(pGDI->DeviceObject[WaveOutDevice],
579: pGDI->BusType,
580: pGDI->BusNumber,
581: NULL,
582: Latched,
583: FALSE,
584: NULL,
585: &port,
586: 4))) {
587: return FALSE;
588: }
589:
590: b0=READ_PORT_UCHAR(pGDI->PASInfo.PROBase + port+0);
591: b1=READ_PORT_UCHAR(pGDI->PASInfo.PROBase + port+1);
592: b2=READ_PORT_UCHAR(pGDI->PASInfo.PROBase + port+2);
593: b3=READ_PORT_UCHAR(pGDI->PASInfo.PROBase + port+3);
594:
595: if (b0==b1 && b1==b2 && b2==b3)
596: return TRUE;
597: else
598: return FALSE;
599:
600: }
601: /*\
602: ;---|*|------====< int WakeUpAtAddress(WORD wPort) >====------
603: ;---|*|
604: ;---|*| Tries to wake up sleeping relocatable hardware at a specified
605: ;---|*| address. Does not check for hardware already in that location
606: ;---|*| If it does wake up a card, it does the minimum amount of
607: ;---|*| initialization to enable the hardware.
608: ;---|*|
609: ;---|*| Entry Conditions:
610: ;---|*| wPort= Base I/O address to wake card up at.
611: ;---|*|
612: ;---|*| Exit Conditions:
613: ;---|*| Returns AX=PORT ADDRESS if Pro AudioSpectrum found
614: ;---|*| Returns AX=0 if Pro AudioSpectrum not available
615: ;---|*|
616: ; \*/
617: BOOLEAN
618: WakeUpAtAddress(
619: PGLOBAL_DEVICE_INFO pGDI,
620: ULONG wPort,
621: FOUNDINFO *pFoundInfo )
622: {
623: int i,j;
624:
625: for (i = 0; i < sizeof(SignatureTable) / sizeof(SignatureTable[0]); i++)
626: {
627: for (j = 0; j < 20; j++)
628: {
629: WRITE_PORT_UCHAR(pGDI->PASInfo.PROBase + PAS_2_WAKE_UP_REG, SignatureTable[i]);
630: KeStallExecutionProcessor(1);
631: WRITE_PORT_UCHAR(pGDI->PASInfo.PROBase + PAS_2_WAKE_UP_REG, (UCHAR)((wPort >> 2) & 0xFF));
632: KeStallExecutionProcessor(1);
633: }
634:
635: if (VerifyProHardware(pGDI, wPort, pFoundInfo))
636:
637: //
638: // Found one - wTranslateCode translates to the board's
639: // correct port.
640: //
641:
642: pFoundInfo->Caps.CapsBits.Did_HW_Init=TRUE;
643:
644: if (pFoundInfo->wBoardRev > PAS_VERSION_1 )
645: {
646: /* Only enable FM feature if we're going to sit at
647: the right address */
648:
649: UCHAR Features = PCM_FEATURE_ENABLE | MIXER_FEATURE_ENABLE |
650: SB_FEATURE_ENABLE | FM_FEATURE_ENABLE;
651:
652: PASX_OUT(pFoundInfo, FEATURE_ENABLE, Features);
653: }
654:
655: return (TRUE);
656: }
657: return (FALSE); // not found
658:
659: }
660:
661: /*\
662: ;---|*|------====< BOOL VerifyLegalAddress(WORD wPort) >====------
663: ;---|*|
664: ;---|*| Tests a caller-nominated base port address for being a legal
665: ;---|*| place for a relocatable PAS to reside.
666: ;---|*|
667: ;---|*| Entry Conditions:
668: ;---|*| wPort= Base I/O address to check
669: ;---|*|
670: ;---|*| Exit Conditions:
671: ;---|*| Returns AX= TRUE if the address is legal
672: ;---|*| Returns AX= FALSE otherwise
673: ;---|*|
674: ; \*/
675: BOOLEAN
676: VerifyLegalAddress(ULONG wPort)
677: {
678: if ((wPort <0x240) || (wPort > 0x3c0) || (wPort & 0xf))
679: return FALSE;
680: else
681: return TRUE;
682: }
683:
684: void InitPasAndMixer(PFOUNDINFO pFI, PSB_CONFIG_DATA ConfigData)
685: {
686: InitProHardware(pFI, ConfigData);
687: InitMixerState(pFI);
688: }
689:
690: void InitProHardware(PFOUNDINFO pFI, PSB_CONFIG_DATA ConfigData)
691: {
692: UCHAR bInput;
693: int i;
694:
695: //if (!pf.ProCard.Caps.CapsBits.Did_HW_Init)
696: // continue; // not sure about this
697:
698: switch (pFI->wBoardRev) {
699:
700: case PAS_VERSION_1:
701: break;
702:
703:
704: //case PAS_PLUS: // same boardrev as PAS_SIXTEEN
705: case PAS_CDPC:
706: case PAS_SIXTEEN:
707:
708: // no interrupts, please!
709: PASX_OUT(pFI, INTERRUPT_ENABLE, 0 );
710: PASX_OUT(pFI, INTERRUPT_CTRL_REG, 0 );
711:
712: if (pFI->wBoardRev == PAS_CDPC || pFI->Caps.CapsBits.DAC16) {
713: //
714: // PAS 16 or CDPC
715: //
716:
717: PASX_OUT(pFI, FEATURE_ENABLE,PCM_FEATURE_ENABLE |
718: FM_FEATURE_ENABLE |
719: MIXER_FEATURE_ENABLE |
720: SB_FEATURE_ENABLE);
721: } else {
722: //
723: // PAS plus
724: //
725:
726: PASX_OUT(pFI, FEATURE_ENABLE,PCM_FEATURE_ENABLE |
727: FM_FEATURE_ENABLE |
728: SB_FEATURE_ENABLE);
729:
730: }
731:
732: PASX_OUT(pFI, PCM_CONTROL,PCM_STEREO|PCM_ENGINE);
733:
734: //
735: // disable original PAS emulation
736: //
737:
738: bInput = PASX_IN(pFI, SYSTEM_CONFIG_1 );
739: bInput = bInput | 2;
740:
741: PASX_OUT(pFI, SYSTEM_CONFIG_1, bInput ); // set sys config 1
742:
743: KeStallExecutionProcessor(10); // wait 10 units?
744:
745: PASX_OUT(pFI, SYSTEM_CONFIG_2, 0 ); // set sys config 2
746:
747: if (pFI->wBoardRev != PAS_CDPC) {
748:
749: PASX_OUT(pFI, SYSTEM_CONFIG_3,C3_ENHANCED_TIMER |
750: C3_INVERT_BCLK |
751: C3_SYNC_PULSE);
752: } else {
753: PASX_OUT(pFI, SYSTEM_CONFIG_3, 0);
754: }
755:
756: // if (pf.ProCard[0].wChipRev >= CHIP_REV_D)
757: // {
758: PASX_OUT(pFI, EMULATION_ADDRESS_POINTER,
759: (MPU_ADDR&0x0f0)+((ConfigData->Port & 0x0f0)>>4) );
760:
761: pFI->MPUPort=MPU_ADDR;
762: pFI->SBPort=ConfigData->Port;
763:
764: PASX_OUT(pFI, EMULATION_INTERRUPT_POINTER,
765: (SOUND_DEF_DMACHANNEL << 6)+
766: ((ConfigData->InterruptNumber == 9 ? 2 :
767: ConfigData->InterruptNumber)<<3)+
768: MPU_EMUL_IRQ);
769:
770: pFI->MPUIRQ=MPU_IRQ;
771: pFI->SBIRQ=ConfigData->InterruptNumber;
772: pFI->SBDMA=SOUND_DEF_DMACHANNEL;
773:
774:
775: PASX_OUT(pFI,
776: COMPATIBLE_REGISTER_ENABLE,
777: COMPAT_MPU+COMPAT_SB);
778: // }
779:
780: PASX_OUT(pFI, INTERRUPT_ENABLE, INT_SB );
781: if (pFI->wBoardRev == PAS_CDPC || !pFI->Caps.CapsBits.DAC16) {
782: PASX_OUT(pFI, FILTER_REGISTER, FILTER_NOMUTE );
783: }
784:
785: break;
786:
787:
788: } // switch (wBoardRev);
789: }
790:
791: #define INPUT_VOLUME 0xd8d8
792: #define OUTPUT_VOLUME 0xc0c0
793: #define MAX_OUTPUT_VOLUME 0xFFFF
794: void
795: InitMixerState(PFOUNDINFO pFI)
796: {
797: dprintf4(("Calling SetFilter"));
798: SetFilter(pFI, FILTER_MUTE);
799:
800: SetInput(pFI,
801: IN_SYNTHESIZER, // input number (see patch.h)
802: INPUT_VOLUME, // range 0-31
803: _LEFT, // _LEFT or _RIGHT (can't do both at once)
804: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
805: OUT_AMPLIFIER); // output number (see patch.h)
806:
807:
808: SetInput(pFI,
809: IN_SYNTHESIZER, // input number (see patch.h)
810: INPUT_VOLUME, // range 0-31
811: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
812: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
813: OUT_AMPLIFIER); // output number (see patch.h)
814:
815: SetInput(pFI,
816: IN_MIXER, // input number (see patch.h)
817: 0, //INPUT_VOLUME, // range 0-31
818: _LEFT, // _LEFT or _RIGHT (can't do both at once)
819: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
820: OUT_AMPLIFIER ); // output number (see patch.h)
821:
822: SetInput(pFI,
823: IN_MIXER, // input number (see patch.h)
824: 0, //INPUT_VOLUME, // range 0-31
825: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
826: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
827: OUT_AMPLIFIER); // output number (see patch.h)
828:
829: SetInput(pFI,
830: IN_EXTERNAL, // input number (see patch.h)
831: INPUT_VOLUME, // range 0-31
832: _LEFT, // _LEFT or _RIGHT (can't do both at once)
833: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
834: OUT_AMPLIFIER); //OUT_PCM ); // output number (see patch.h)
835:
836: SetInput(pFI,
837: IN_EXTERNAL, // input number (see patch.h)
838: INPUT_VOLUME, // range 0-31
839: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
840: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
841: OUT_AMPLIFIER); //OUT_PCM ); // output number (see patch.h)
842:
843: SetInput(pFI,
844: IN_INTERNAL, // input number (see patch.h)
845: INPUT_VOLUME, // range 0-31
846: _LEFT, // _LEFT or _RIGHT (can't do both at once)
847: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
848: OUT_AMPLIFIER); //OUT_PCM ); // output number (see patch.h)
849:
850: SetInput(pFI,
851: IN_INTERNAL, // input number (see patch.h)
852: INPUT_VOLUME, // range 0-31
853: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
854: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
855: OUT_AMPLIFIER); //OUT_PCM ); // output number (see patch.h)
856:
857: SetInput(pFI,
858: IN_MICROPHONE, // input number (see patch.h)
859: INPUT_VOLUME, // range 0-31
860: _LEFT, // _LEFT or _RIGHT (can't do both at once)
861: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
862: OUT_PCM ); // output number (see patch.h)
863:
864: SetInput(pFI,
865: IN_MICROPHONE, // input number (see patch.h)
866: INPUT_VOLUME, // range 0-31
867: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
868: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
869: OUT_PCM ); // output number (see patch.h)
870:
871: SetInput(pFI,
872: IN_PCM, // input number (see patch.h)
873: 0, //INPUT_VOLUME, // range 0-31
874: _LEFT, // _LEFT or _RIGHT (can't do both at once)
875: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
876: OUT_AMPLIFIER ); // output number (see patch.h)
877:
878: SetInput(pFI,
879: IN_PCM, // input number (see patch.h)
880: 0, //INPUT_VOLUME, // range 0-31
881: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
882: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
883: OUT_AMPLIFIER ); // output number (see patch.h)
884:
885: SetInput(pFI,
886: IN_PC_SPEAKER, // input number (see patch.h)
887: INPUT_VOLUME, // range 0-31
888: _LEFT, // _LEFT or _RIGHT (can't do both at once)
889: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
890: OUT_AMPLIFIER ); // output number (see patch.h)
891:
892: SetInput(pFI,
893: IN_PC_SPEAKER, // input number (see patch.h)
894: INPUT_VOLUME, // range 0-31
895: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
896: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
897: OUT_AMPLIFIER ); // output number (see patch.h)
898:
899: #if 0
900: SetInput(pFI,
901: IN_SNDBLASTER, // input number (see patch.h)
902: SBWaveOutVolume.Left, // range 0-31
903: _LEFT, // _LEFT or _RIGHT (can't do both at once)
904: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
905: OUT_AMPLIFIER ); // output number (see patch.h)
906:
907: SetInput(pFI,
908: IN_SNDBLASTER, // input number (see patch.h)
909: SBWaveOutVolume.Right, // gain range 0-31
910: _RIGHT, // _LEFT or _RIGHT (can't do both at once)
911: MIXCROSSCAPS_NORMAL_STEREO, // see pasdef.h
912: OUT_AMPLIFIER ); // output number (see patch.h)
913: #endif
914:
915: SetOutput(pFI,
916: OUT_AMPLIFIER, // output number
917: OUTPUT_VOLUME, // volume range 0-63
918: _LEFT ); // _LEFT or _RIGHT (can't do both at once)
919:
920: SetOutput(pFI,
921: OUT_AMPLIFIER, // output number
922: OUTPUT_VOLUME, // volume range 0-63
923: _RIGHT ); // _LEFT or _RIGHT (can't do both at once)
924:
925: SetOutput(pFI,
926: OUT_PCM, // output number
927: MAX_OUTPUT_VOLUME, // volume range 0-63
928: _LEFT ); // _LEFT or _RIGHT (can't do both at once)
929:
930: SetOutput(pFI,
931: OUT_PCM, // output number
932: MAX_OUTPUT_VOLUME, // volume range 0-63
933: _RIGHT ); // _LEFT or _RIGHT (can't do both at once)
934:
935: SetFilter(pFI, FILTER_LEVEL_6);
936:
937: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.