mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
303 lines
7.9 KiB
303 lines
7.9 KiB
/*++
|
|
|
|
Copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
findpas.c
|
|
|
|
Abstract:
|
|
|
|
This module contains code configuration code MediaVision's Pro audio
|
|
spectrum. The card is run in Sound Blaster compatibiltiy mode.
|
|
|
|
Support is provided for volume setting and line input and
|
|
microphone mix level setting.
|
|
|
|
The card is located by searching. No user configuration is supported.
|
|
|
|
Author:
|
|
|
|
Adapted from work by Robin Speed (RobinSp) 17-Oct-1992
|
|
|
|
Environment:
|
|
|
|
Kernel mode
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include CARDTXXX_H
|
|
#include "findpas.h"
|
|
|
|
|
|
|
|
//--------------========================---------------------------
|
|
//---------====< GLOBAL DATA SECTION >====-------------------------
|
|
//--------------========================---------------------------
|
|
|
|
// The board signature is the first value in the PAS 16 wakeup sequence
|
|
// BC is the factory default. A board jumpered to recognize the BD signature
|
|
// will not respond to a BC init command.
|
|
|
|
UCHAR SignatureTable[4]={0xBC,0xBD,0xBE,0xBF};
|
|
|
|
//
|
|
// MPU stuff here until we work out what we want
|
|
//
|
|
|
|
#define MPU_ADDR 0x330
|
|
|
|
#define MPU_IRQ 2
|
|
#define MPU_EMUL_IRQ EMUL_IRQ_2
|
|
|
|
|
|
//
|
|
// Local routines
|
|
//
|
|
|
|
|
|
BOOLEAN
|
|
VerifyProHardware(
|
|
PFOUNDINFO pFI,
|
|
ULONG port);
|
|
|
|
BOOLEAN
|
|
WakeUpAtAddress(
|
|
PFOUNDINFO pFoundInfo,
|
|
ULONG wPort);
|
|
|
|
; /*\
|
|
;---|*|------====< DWORD GetProTableRead() >====------
|
|
;---|*|
|
|
;---|*| Detects which version of the Pro AudioSpectrum is installed
|
|
;---|*|
|
|
;---|*| Entry Conditions:
|
|
;---|*| Pointer to Profile Structure. If the caller wants to specify
|
|
;---|*| the preferred base address for cards not yet init'd, they
|
|
;---|*| are passed in this structure. The NumFound field indicates
|
|
;---|*| the number of location requests and the board address elements
|
|
;---|*| indicate the locations.
|
|
;---|*|
|
|
;---|*| Also passed in pointer to port (the one we found in the registry
|
|
;---|*| if any
|
|
;---|*|
|
|
;---|*| Exit Conditions:
|
|
;---|*| Returns number of cards found
|
|
;---|*| ProFile structure has been updated.
|
|
;---|*|
|
|
; \*/
|
|
|
|
|
|
int
|
|
FindPasHardware(
|
|
PFOUNDINFO pFoundInfo
|
|
)
|
|
// PSB_CONFIG_DATA ConfigData )
|
|
{
|
|
|
|
if (WakeUpAtAddress(pFoundInfo, pFoundInfo->ProPort)) {
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
; /*\
|
|
;---|*|------====< int VerifyProHardware() >====------
|
|
;---|*|
|
|
;---|*| Detects which version of the Pro AudioSpectrum is installed
|
|
;---|*|
|
|
;---|*| Entry Conditions:
|
|
;---|*| pFI - found info pointer -- has PROBase mapped I/O space.
|
|
;---|*| port - I/O port location to search -- not mapped.
|
|
;---|*|
|
|
;---|*| Exit Conditions:
|
|
;---|*| Returns TRUE if ProAudio found.
|
|
;---|*| Returns FALSE if not found.
|
|
;---|*|
|
|
; \*/
|
|
|
|
|
|
BOOLEAN
|
|
VerifyProHardware(
|
|
PFOUNDINFO pFI,
|
|
ULONG port)
|
|
{
|
|
UCHAR bData, bTemp;
|
|
|
|
DebugPrint((DEBUG_LEVEL,"VerifyProHardware (proport %X,probase %X, port %X)\n",pFI->ProPort,pFI->PROBase,port));
|
|
pFI->TranslateCode = port ^ DEFAULT_BASE;
|
|
|
|
bData=PASX_IN (pFI, INTERRUPT_CTRL_REG);
|
|
|
|
if (bData==0xFF) { // 0xFF usually means nothing there
|
|
goto VerifyFailed;
|
|
}
|
|
pFI->wBoardRev= (bData >>5); // board rev is 3 topmost bits
|
|
|
|
switch (pFI->wBoardRev) {
|
|
#ifndef WINNT
|
|
// winnt does not want support for old cards, this code recognizes
|
|
// some sound blasters
|
|
case PAS_VERSION_1:
|
|
#endif
|
|
//case PAS_PLUS: // same boardrev as PAS_SIXTEEN
|
|
case PAS_STUDIO:
|
|
case PAS_SIXTEEN:
|
|
case PAS_CDPC:
|
|
case 4: // Memphis
|
|
break;
|
|
|
|
default:
|
|
goto VerifyFailed; // unknown hardware type
|
|
}
|
|
|
|
PASX_OUT(pFI, INTERRUPT_CTRL_REG, bData ^ 0xE0); // try changing version bits
|
|
bTemp=PASX_IN (pFI, INTERRUPT_CTRL_REG); // they should be read only
|
|
|
|
if ((bTemp & (D7+D6+D5)) != (bData & (D7+D6+D5))) {
|
|
PASX_OUT(pFI, INTERRUPT_CTRL_REG, bData); // Excuse me, stranger.
|
|
goto VerifyFailed;
|
|
}
|
|
|
|
if (pFI->wBoardRev==PAS_VERSION_1) {
|
|
|
|
pFI->Caps.CapsBits.CDInterfaceType=SCSI_TYPE;
|
|
|
|
//
|
|
// test for Enhanced SCSI mod (U48)
|
|
//
|
|
|
|
PASX_OUT(pFI, ENHANCED_SCSI_DETECT_REG, 0 ); // write to try changing version bits
|
|
ScsiPortStallExecution(10); // wait 10 us
|
|
bTemp=PASX_IN ( pFI, ENHANCED_SCSI_DETECT_REG ); // they should be read only
|
|
|
|
switch (bTemp & 1) { // bit0==1 means old SCSI PAL
|
|
case 0:
|
|
pFI->Caps.CapsBits.EnhancedSCSI=TRUE;
|
|
// allow to fall thru
|
|
|
|
case 1:
|
|
goto ProVerified;
|
|
}
|
|
} else {
|
|
// if PAS hardware installed, the reset bit can never be on
|
|
|
|
bTemp=PASX_IN (pFI, SYSTEM_CONFIG_1); // get PAS config register
|
|
if (bTemp & D7) { // D7 is reset bit
|
|
goto VerifyFailed;
|
|
}
|
|
|
|
bTemp=PASX_IN (pFI, SLAVE_MODE_READ);
|
|
|
|
if (bTemp & SLAVE_MODE_OPL3) {
|
|
pFI->Caps.CapsBits.OPL_3=TRUE;
|
|
}
|
|
|
|
if (bTemp & SLAVE_MODE_16) {
|
|
pFI->Caps.CapsBits.DAC16=TRUE;
|
|
pFI->Caps.CapsBits.DualDAC=TRUE;
|
|
|
|
// if 16-bit DAC, and not a CDPC, it has a 508 chip.
|
|
// Note: PAS 16 w/ VGA will have Mixer 508 also.
|
|
|
|
if (pFI->wBoardRev != PAS_CDPC) {
|
|
pFI->Caps.CapsBits.Mixer_508=TRUE;
|
|
}
|
|
}
|
|
|
|
pFI->Caps.CapsBits.CDInterfaceType=(bTemp & (D1+D0));
|
|
|
|
if (pFI->Caps.CapsBits.CDInterfaceType==SCSI_TYPE) {
|
|
pFI->Caps.CapsBits.SCSI_IO_16=TRUE;
|
|
}
|
|
|
|
pFI->Caps.CapsBits.Slot16=TRUE;
|
|
pFI->Caps.CapsBits.SoundBlaster=TRUE;
|
|
|
|
bTemp=PASX_IN (pFI, MASTER_MODE_READ); // get slave bits
|
|
if ((bTemp & D0)==0) {
|
|
pFI->Caps.CapsBits.MCA=TRUE;
|
|
}
|
|
|
|
if (bTemp & D2) {
|
|
pFI->Caps.CapsBits.CDPC=TRUE;
|
|
}
|
|
|
|
pFI->wChipRev=PASX_IN (pFI, CHIP_REV);
|
|
}
|
|
|
|
ProVerified:
|
|
|
|
DebugPrint((DEBUG_LEVEL,"\n\nFound PRO hardware at %X\n", port));
|
|
pFI->ProPort=port; // found at this port
|
|
return TRUE;
|
|
|
|
////////////////////////////////
|
|
|
|
VerifyFailed:
|
|
pFI->wBoardRev=0; // found at this port
|
|
pFI->Caps.dwCaps=0; // No Board, No Caps
|
|
return FALSE;
|
|
}
|
|
|
|
; /*\
|
|
;---|*|------====< int WakeUpAtAddress(WORD wPort) >====------
|
|
;---|*|
|
|
;---|*| Tries to wake up sleeping relocatable hardware at a specified
|
|
;---|*| address. Does not check for hardware already in that location
|
|
;---|*| If it does wake up a card, it does the minimum amount of
|
|
;---|*| initialization to enable the hardware.
|
|
;---|*|
|
|
;---|*| Entry Conditions:
|
|
;---|*| wPort= Base I/O address to wake card up at.
|
|
;---|*|
|
|
;---|*| Exit Conditions:
|
|
;---|*| Returns TRUE if ProAudio hardware found.
|
|
;---|*| Returns FALSE if not.
|
|
;---|*|
|
|
; \*/
|
|
BOOLEAN
|
|
WakeUpAtAddress(
|
|
PFOUNDINFO pFoundInfo,
|
|
ULONG wPort)
|
|
{
|
|
int i,j;
|
|
|
|
DebugPrint((DEBUG_LEVEL,"WakeUpAtAddress (proport %X,probase %X, port %X)\n",pFoundInfo->ProPort,pFoundInfo->PROBase,wPort));
|
|
for (i = 0; i < sizeof(SignatureTable) / sizeof(SignatureTable[0]); i++) {
|
|
for (j = 0; j < 20; j++) {
|
|
WRITE_PORT_UCHAR(pFoundInfo->PROBase + PAS_2_WAKE_UP_REG, SignatureTable[i]);
|
|
ScsiPortStallExecution(1);
|
|
WRITE_PORT_UCHAR(pFoundInfo->PROBase + PAS_2_WAKE_UP_REG, (UCHAR)((wPort >> 2) & 0xFF));
|
|
ScsiPortStallExecution(1);
|
|
}
|
|
|
|
if (VerifyProHardware(pFoundInfo, wPort)) {
|
|
|
|
//
|
|
// Found one - wTranslateCode translates to the board's
|
|
// correct port.
|
|
//
|
|
|
|
pFoundInfo->Caps.CapsBits.Did_HW_Init=TRUE;
|
|
|
|
if (pFoundInfo->wBoardRev > PAS_VERSION_1 ) {
|
|
/* Only enable FM feature if we're going to sit at
|
|
the right address */
|
|
|
|
UCHAR Features = PCM_FEATURE_ENABLE | MIXER_FEATURE_ENABLE |
|
|
SB_FEATURE_ENABLE | FM_FEATURE_ENABLE;
|
|
|
|
PASX_OUT(pFoundInfo, FEATURE_ENABLE, Features);
|
|
}
|
|
|
|
return (TRUE);
|
|
}
|
|
}
|
|
return (FALSE); // not found
|
|
}
|
|
|