Annotation of ntddk/src/mmedia/sndblst/driver/pas.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.