📄 w99av.c
字号:
{
// Chuan0.83a, EPP don't need delay.
#ifndef IO_EPP
_inp(__wW99AVPCIIO);
#endif //
}
#endif
// ***********************************************************************
// Function : W99AV_ReadInternalRegDW
// Description : Read a value (DWORD) from a register by command
// : via AIR, DPR, disable interrupt during R/W
// Arguments : bReg:Index of a register (only BYTE is valid)
// Return : Content of the register
// Side Effect :
// ***********************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
DWORD W99AV_ReadInternalRegDW(BYTE bReg)
{
#ifdef GLOBAL_BUS_IO
#if IO == IO_PCI
// Step 1 : Host writes GBAR to specify the address of the global bus register to be read.
// Chuan0.81, Use PCI Delay
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBAR_BYTE, bReg);
// Step 2 : Host writes ACM=01 into GBDR2 to specify a read command
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR2_BYTE, 0x40);
#else
// Step 1 : Host writes GBAR to specify the address of the global bus register to be read.
OUTB(GBAR, bReg);
// Step 2 : Host writes GBDR0, GBDR1 with contents to be written into the lower 16 bits of the global bus register
OUTB(GBDR2, 0x40);
#endif
// Step 3: waiting for Command acknowledge
if (_W99AV_WaitACK(INT_CACK))
{
_bIdx =(BYTE *) &_dwTemp ;
#if IO == IO_PCI
// Chuan0.81, Use PCI Delay
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay (DELAY) ;
W99AV_PCIDelay();
*(_bIdx+2)=_inp((WORD)GBDR2_BYTE); // discard the value of first time reading
//_Delay (DELAY) ;
W99AV_PCIDelay();
#endif //
*(_bIdx+2)=_inp((WORD)GBDR2_BYTE); // the valid value
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay (DELAY) ;
W99AV_PCIDelay();
*(_bIdx+1)=_inp((WORD)GBDR1_BYTE); // discard the value of first time reading
//_Delay (DELAY) ;
W99AV_PCIDelay();
#endif //
*(_bIdx+1)=_inp((WORD)GBDR1_BYTE); // the valid value
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay (DELAY) ;
W99AV_PCIDelay();
*(_bIdx)=_inp((WORD)GBDR0_BYTE); // discard the value of first time reading
//_Delay (DELAY) ;
W99AV_PCIDelay();
#endif //
*(_bIdx)=_inp((WORD)GBDR0_BYTE); // the valid value
#else
*(_bIdx+1) = INPB (GBDR2) ;
*(_bIdx+2) = INPB (GBDR1) ;
*(_bIdx+3) = INPB (GBDR0) ;
#endif
_dwTemp&=0x0FFFFF;
}
else
_dwTemp=ERROR_VALUE; // Chuan1.05, different ret value between Debug and Release to avoid infinite loop when No Ack at release mode.
#else
__dwW99AVCmdArg[0]=3; // number of the ARG0~ARG15
__dwW99AVCmdArg[1]=CMDARG_ACCREG; // command_arg=0x0800
__dwW99AVCmdArg[2]=0xFFFFFFFF; // don't care
__dwW99AVCmdArg[3]=(DWORD)bReg; // register_index[8]=0 imply read
if(W99AV_CommandN(COMMAND_ACCREG)) // command_index=0x08
{
W99AV_OutIndex(0x10000000);
_dwTemp=W99AV_InData();
}
else
_dwTemp=ERROR_VALUE; // Chuan1.05, different ret value between Debug and Release to avoid infinite loop when No Ack at release mode.
#endif
return _dwTemp;
}
// ***********************************************************************
// Function : W99AV_ReadInternalRegW
// Description : Read a value (WORD) from a register by command
// : via AIR, DPR, disable interrupt during R/W
// Arguments : bReg:Index of a register (only BYTE is valid)
// Return : Content of the register
// Side Effect :
// ***********************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
WORD W99AV_ReadInternalRegW(BYTE bReg)
{
#ifdef GLOBAL_BUS_IO
#if IO == IO_PCI
// Step 1 : Host writes GBAR to specify the address of the global bus register to be read.
// Chuan0.81, Use PCI Delay
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBAR_BYTE, bReg);
// Step 2 : Host writes ACM=01 into GBDR2 to specify a read command
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR2_BYTE, 0x40);
#else
// Step 1 : Host writes GBAR to specify the address of the global bus register to be read.
OUTB(GBAR, bReg);
// Step 2 : Host writes GBDR0, GBDR1 with contents to be written into the lower 16 bits of the global bus register
OUTB(GBDR2, 0x40);
#endif
// Step 3: waiting for Command acknowledge
if (_W99AV_WaitACK(INT_CACK))
{
_bIdx = (BYTE *)&_wTemp ;
#if IO == IO_PCI
// Chuan0.81, Use PCI Delay
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay (DELAY) ;
W99AV_PCIDelay();
*(_bIdx+1)=_inp((WORD)GBDR1_BYTE); // discard the value of first time reading
//_Delay (DELAY) ;
W99AV_PCIDelay();
#endif //
*(_bIdx+1)=_inp((WORD)GBDR1_BYTE); // the valid value
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay (DELAY) ;
W99AV_PCIDelay();
*(_bIdx)=_inp((WORD)GBDR0_BYTE); // discard the value of first time reading
//_Delay (DELAY) ;
W99AV_PCIDelay();
#endif //
*(_bIdx)=_inp((WORD)GBDR0_BYTE); // the valid value
#else
// Chuan0.83, fix a typo
*_bIdx = INPB (GBDR1) ;
*(_bIdx+1) = INPB (GBDR0) ;
#endif
}
else
_wTemp=LOWORD(ERROR_VALUE); // Chuan1.05, different ret value between Debug and Release to avoid infinite loop when No Ack at release mode.
#else
__dwW99AVCmdArg[0]=3; // number of the ARG0~ARG15
__dwW99AVCmdArg[1]=CMDARG_ACCREG; // command_arg=0x0800
__dwW99AVCmdArg[2]=0xFFFFFFFF; // don't care
__dwW99AVCmdArg[3]=(DWORD)bReg; // register_index[8]=0 imply read
if(W99AV_CommandN(COMMAND_ACCREG)) // command_index=0x08
{
W99AV_OutIndex(0x10000000);
_wTemp=(WORD)W99AV_InData();
}
else
_wTemp=LOWORD(ERROR_VALUE); // Chuan1.05, different ret value between Debug and Release to avoid infinite loop when No Ack at release mode.
#endif
return _wTemp;
}
//CoCo.28af
// ***********************************************************************
// Function : W99AV_WriteInternalRegDW
// Description : Write a value (DWORD) to a internal register by command
// Arguments : bReg:the register's index (only BYTE is valid)
// : wLo:the Low Word of the desired value
// : Hi:the high Word of the desired value
// Return : none
// Side Effect :
// ***********************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
void W99AV_WriteInternalRegDW(BYTE bReg, WORD wLo, WORD wHi)
{
#ifdef GLOBAL_BUS_IO
#if IO == IO_PCI
// Step 1 : Host writes GBAR to specify the address of the global bus register to be written.
// Chuan0.81, Use PCI Delay
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBAR_BYTE, bReg);
// Step 2 : Host writes GBDR0, GBDR1 with contents to be written into the lower 16 bits of the global bus register
_bIdx=(BYTE *)&wLo;
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR0_BYTE, *(_bIdx));
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR1_BYTE, *(_bIdx+1));
// Step 3: Host writes GBDR2(3:0) with contents of the higher 4 bits of the global bus register and at the same time writes ACM=10 to specify a write command
_bTemp = (BYTE)(wHi|0x80);
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR2_BYTE, _bTemp);
#else
// Step 1 : Host writes GBAR to specify the address of the global bus register to be written.
OUTB(GBAR, bReg);
// Step 2 : Host writes GBDR0, GBDR1 with contents to be written into the lower 16 bits of the global bus register
_bIdx=(BYTE *)&wLo;
OUTB(GBDR0, *(_bIdx+1));
OUTB(GBDR1, *(_bIdx));
// Step 3: Host writes GBDR2(3:0) with contents of the higher 4 bits of the global bus register and at the same time writes ACM=10 to specify a write command
_bTemp = (BYTE)(wHi|0x80);
OUTB(GBDR2, _bTemp);
#endif
// Step 4: waiting for Command acknowledge
_W99AV_WaitACK(INT_CACK);
#else
__dwW99AVCmdArg[0]=3; // number of ARG0~ARG15
__dwW99AVCmdArg[1]=CMDARG_ACCREG; // Command_arg=0x0800
__dwW99AVCmdArg[2]=MAKELONG(wLo,wHi); // register data
__dwW99AVCmdArg[3]=(DWORD)bReg | 0x00000100; // register_index[8]=1 imply write
W99AV_CommandN(COMMAND_ACCREG); // command_index=0x08;
#endif
}
// ***********************************************************************
// Function : W99AV_WriteInternalRegW
// Description : Write a value (WORD) to a internal register by command
// Arguments : bReg:the register's index (only BYTE is valid)
// : wLo:the Low Word of the desired value
// : Hi:the high Word of the desired value
// Return : none
// Side Effect :
// ***********************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
void W99AV_WriteInternalRegW(BYTE bReg, WORD wLo)
{
#ifdef GLOBAL_BUS_IO
#if IO == IO_PCI
// Step 1 : Host writes GBAR to specify the address of the global bus register to be written.
// Chuan0.81, Use PCI Delay
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBAR_BYTE, bReg);
// Step 2 : Host writes GBDR0, GBDR1 with contents to be written into the lower 16 bits of the global bus register
_bIdx=(BYTE *)&wLo;
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR0_BYTE, *(_bIdx));
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR1_BYTE, *(_bIdx+1));
// Step 3: Host writes GBDR2(3:0) with contents of the higher 4 bits of the global bus register and at the same time writes ACM=10 to specify a write command
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)GBDR2_BYTE, 0x80);
#else
// Step 1 : Host writes GBAR to specify the address of the global bus register to be written.
OUTB(GBAR, bReg);
// Step 2 : Host writes GBDR0, GBDR1 with contents to be written into the lower 16 bits of the global bus register
_bIdx=(BYTE *)&wLo;
OUTB(GBDR0, *(_bIdx+1));
OUTB(GBDR1, *(_bIdx));
// Step 3: Host writes GBDR2(3:0) with contents of the higher 4 bits of the global bus register and at the same time writes ACM=10 to specify a write command
OUTB(GBDR2, 0x80);
#endif
// Step 4: waiting for Command acknowledge
_W99AV_WaitACK(INT_CACK);
#else
__dwW99AVCmdArg[0]=3; // number of ARG0~ARG15
__dwW99AVCmdArg[1]=CMDARG_ACCREG; // Command_arg=0x0800
__dwW99AVCmdArg[2]=(DWORD)wLo; // register data
__dwW99AVCmdArg[3]=(DWORD)bReg | 0x00000100; // register_index[8]=1 imply write
W99AV_CommandN(COMMAND_ACCREG); // command_index=0x08
#endif
}
// **********************************************************************
// Function : W99AV_SetCommandEnable
// Description : Set the command enable bit
// Argument : None
// Return : None
// Side Effect :
// *********************************************************************
#pragma NOAREGS // called in ISR
// Chuan2.80p, create
void W99AV_SetCommandEnable(void)
{
#if IO==IO_PCI
// Chuan0.81, Use PCI Delay
//_Delay (DELAY) ;
W99AV_PCIDelay();
_outp((WORD)CER_BYTE, 0x08);
#else // #if IO==IO_PCI
OUTB(CER, 0x08);
#endif // #if IO==IO_PCI
}
//Kevin2.37, create
// **********************************************************************
// Description : Feed data to Input-Audio-Bitstream FIFO (ACFIFO)
// Argument : wWords: # of words
// pwData: const code ptr => common bank
// Return : None
// *********************************************************************
void W99AV_FillDataToIABFIFO(WORD wWords, WORD code *pwData)
{
extern BYTE *_bpArray;
W99AV_WriteRegDW( PCR, __wW99AVPCRLow, (WORD)(__wW99AVPCRHigh | 0x400) );
_bpArray = (BYTE *)pwData;
for (_wTemp = 0; _wTemp < wWords; _wTemp++)
{
#ifdef SYSTEM_8051
OUTB(IADPR0,_bpArray[1]);
OUTB(IADPR0,_bpArray[0]);
#else
_outp((WORD)IADPR0, _bpArray[0]);
_outp((WORD)IADPR0, _bpArray[1]);
#endif
_bpArray+=2;
}
//flush IFIFO/ACFIFO/ABUF & add more s.t. gzippram.inc won't wait for buffer remainder to be larger than a threshold
for (_bTemp = 0; _bTemp < 255; _bTemp++)
{
#ifdef SYSTEM_8051
OUTB(IADPR0,0x00);
OUTB(IADPR0,0x00);
OUTB(IADPR0,0x00);
OUTB(IADPR0,0x00);
#else
_outp((WORD)IADPR0, 0x00);
_outp((WORD)IADPR0, 0x00);
_outp((WORD)IADPR0, 0x00);
_outp((WORD)IADPR0, 0x00);
#endif
}
W99AV_WriteRegDW (PCR, __wW99AVPCRLow, __wW99AVPCRHigh) ;
}
//Kevin2.31, use CT_strxxx functions instead of string library to save code size
char * CT_strcpy(char * s1, char *s2)
{
char *tmp=s1;
while ((*s1++ = *s2++) != '\0')
/* nothing */;
return tmp;
}
char * CT_strncpy(char * s1,char *s2,int n)
{
char *tmp = s1;
while (n-- && (*s1++ = *s2++) != '\0')
/* nothing */;
return tmp;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -