|
|
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.