Annotation of ntddk/src/mmedia/sndblst/driver/pas.c, revision 1.1.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.