[recovery mode] Старые ISA-видеокарты и AVR
//****************************************************************************************************
//функции для работы с видеокартой oak
//****************************************************************************************************
//****************************************************************************************************
//макроопределения
//****************************************************************************************************
//****************************************************************************************************
//глобальные переменные
//****************************************************************************************************
unsigned char OAK_InitData[77] PROGMEM=
{
0x01,0x29,0x04,0x10,0x07,0x00,0x01,0x3E,
0x00,0x00,0x80,0x70,0xFF,0x01,0xFF,0xFF,
0x7F,0x00,0xFF,0xC8,0x00,0x00,0xFF,0x00,
0x01,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x01,0x00,0x08,0x00,0x00,0x00,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,
0x00,0x00,0x00,0x00,0x10
};
//****************************************************************************************************
//прототипы функций
//****************************************************************************************************
CHIP_TYPE OAK_Init(void);//тест видеокарты как Trident
unsigned char OAK_TestInx2(unsigned short rg,unsigned char ix,unsigned char msk);//возвращает true, если бит MSK регистра PT по индексу RG равен 1
void OAK_OTI077_Init(void);//инициализация OAK077
void OAK_OTI087_Init(void);//инициализация OAK087
void OAK_Unit218C(void);//модуль 218C
void OAK_Unit201B(void);//модуль 201B
void OAK_Unit50F(void);//модуль 50F
void OAK_Unit58F(unsigned char ah,unsigned char al);//модуль 58F
void OAK_Unit552(void);//модуль 552
unsigned char OAK_Unit53D(void);//модуль 53D
void OAK_Unit21A8(void);//модуль 21A8
void OAK_Fill3DE(void);//модуль Fill3DE
bool OAK_Unit21C9(void);//модуль 21C9
void OAK_Unit2167(unsigned short addr,unsigned char v);//модуль 2167
void OAK_Unit2148(unsigned char v);//модуль 2148
void OAK_Unit2A0F(void);//модуль 2A0F
void OAK_Unit28E2(unsigned char al,unsigned char ah);//модуль 28E2
void OAK_Unit28AC(unsigned char al,unsigned char ah);//модуль 28AC
void OAK_Unit29E0(void);//модуль 29E0
unsigned char OAK_Unit1CED(void);//модуль 1CED
void OAK_Unit1E12(void);//модуль 1E12
void OAK_Unit292D(unsigned char al,unsigned char bl,unsigned char bh);//модуль 292D
//****************************************************************************************************
//реализация функций
//****************************************************************************************************
//----------------------------------------------------------------------------------------------------
//тест видеокарты как Trident
//----------------------------------------------------------------------------------------------------
CHIP_TYPE OAK_Init(void)
{
CHIP_TYPE chiptype=UNKNOWN;
VGA_Reset();
System_Out8(0x46E8,0x17);
System_Out8(0x0102,System_In8(0x0102)|1);
System_Out8(0x46E8,0x0F);
if (OAK_TestInx2(0x3DE,0x0D,0x38))
{
if (OAK_TestInx2(0x3DE,0x23,0x1F))
{
if((VGA_InReg8(0x3DE,0x00)&0x02)==0)
{
chiptype=OAK_087;
OAK_OTI087_Init();
}
else chiptype=OAK_083;
}
else
{
switch(System_In8(0x3DE)/32)
{
case 0:
chiptype=OAK_037C;
break;
case 2:
chiptype=OAK_067;
break;
case 5:
chiptype=OAK_077;
OAK_OTI077_Init();
break;
case 7:
chiptype=OAK_057;
break;
}
}
}
return(chiptype);
}
//----------------------------------------------------------------------------------------------------
//возвращает true, если бит MSK регистра PT по индексу RG равен 1
//----------------------------------------------------------------------------------------------------
unsigned char OAK_TestInx2(unsigned short rg,unsigned char ix,unsigned char msk)
{
unsigned char old,nw1,nw2;
old=VGA_InReg8(rg,ix);
VGA_OutReg8(rg,ix,old&(~msk));
nw1=VGA_InReg8(rg,ix)&msk;
VGA_OutReg8(rg,ix,old|msk);
nw2=VGA_InReg8(rg,ix)&msk;
VGA_OutReg8(rg,ix,old<<8);
return((nw1==0)&(nw2==msk));
}
//----------------------------------------------------------------------------------------------------
//инициализация OAK087
//----------------------------------------------------------------------------------------------------
void OAK_OTI087_Init(void)
{
System_Out8(0x320,1);
System_In8(0x320);
OAK_Unit218C();
VGA_OutReg8(0x3DE,0x13,VGA_InReg8(0x3DE,0x13)&0xBF);
VGA_OutReg8(0x3DE,0x0B,((VGA_InReg8(0x3DE,0x0B)&0x0F)|(VGA_InReg8(0x3DE,0x10)))&0xF0);
OAK_Unit201B();
OAK_Unit50F();
OAK_Unit552();
System_Out8(0x320,2);
OAK_Fill3DE();
OAK_Unit21A8();
OAK_Unit218C();
System_Out8(0x320,0x0c);
System_Out8(0x46E8,0x17);
System_Out8(0x0102,System_In8(0x0102)|1);
System_Out8(0x46E8,0x0F);
OAK_Fill3DE();
}
//----------------------------------------------------------------------------------------------------
//инициализация OAK077
//----------------------------------------------------------------------------------------------------
void OAK_OTI077_Init(void)
{
OAK_Unit2A0F();
VGA_OutReg8(0x3DE,0x0E,VGA_InReg8(0x3DE,0x0E)&0xDE);
OAK_Unit1E12();
System_Out8(0x46E8,0x17);
System_Out8(0x0102,System_In8(0x0102)|1);
System_Out8(0x46E8,0x0F);
}
//----------------------------------------------------------------------------------------------------
//модуль 218C
//----------------------------------------------------------------------------------------------------
void OAK_Unit218C(void)
{
OAK_Unit2148(0x0F);
if (OAK_Unit21C9()==false) return;
OAK_Unit2167(0x0094,0x01);
if (OAK_Unit21C9()==false) return;
OAK_Unit2167(0x0394,0x01);
return;
}
//----------------------------------------------------------------------------------------------------
//модуль 201B
//----------------------------------------------------------------------------------------------------
void OAK_Unit201B(void)
{
unsigned char ah;
System_In8(0x3C8);
ah=System_In8(0x3C6);
System_In8(0x3C8);
System_In8(0x3C6);
System_In8(0x3C6);
System_In8(0x3C6);
System_In8(0x3C6);
System_Out8(0x3C6,0);
System_In8(0x3C8);
System_Out8(0x3C6,ah);
System_In8(0x3C8);
}
//----------------------------------------------------------------------------------------------------
//модуль 50F
//----------------------------------------------------------------------------------------------------
void OAK_Unit50F(void)
{
if ((VGA_InReg8(0x3DE,0x07)&0x04)) return;
OAK_Unit58F(0xFF,0x05);
}
//----------------------------------------------------------------------------------------------------
//модуль 58F
//----------------------------------------------------------------------------------------------------
void OAK_Unit58F(unsigned char ah,unsigned char al)
{
System_Out8(0x1E,al);
System_Out8(0x1F,ah);
}
//----------------------------------------------------------------------------------------------------
//модуль 552
//----------------------------------------------------------------------------------------------------
void OAK_Unit552(void)
{
if (OAK_Unit53D()) return;
OAK_Unit58F(0x07,0x04);
OAK_Unit58F(0xFF,0x05);
OAK_Unit58F((VGA_InReg8(0x1E,0xFE)|0x40),0xFE);
}
//----------------------------------------------------------------------------------------------------
//модуль 53D
//----------------------------------------------------------------------------------------------------
unsigned char OAK_Unit53D(void)
{
if (VGA_InReg8(0x3DE,0x07)&0x04) return(1);
return(VGA_InReg8(0x3DE,0x08)&0x03);
}
//----------------------------------------------------------------------------------------------------
//модуль 21A8
//----------------------------------------------------------------------------------------------------
void OAK_Unit21A8(void)
{
if (VGA_InReg8(0x3DE,0x07)&0x04) OAK_Unit2148(0x00);
else
{
OAK_Unit2167(0x0094,0x00);
OAK_Unit2167(0x0394,0x00);
}
}
//----------------------------------------------------------------------------------------------------
//модуль Fill3DE
//----------------------------------------------------------------------------------------------------
void OAK_Fill3DE(void)
{
unsigned char i;
for(i=0;i<77;i++)
{
unsigned short byte=pgm_read_byte(&(OAK_InitData[i]));
VGA_OutReg8(0x3DE,i,byte);
}
}
//----------------------------------------------------------------------------------------------------
//модуль 21C9
//----------------------------------------------------------------------------------------------------
bool OAK_Unit21C9(void)
{
unsigned char al=0x55,ah=al;
while(1)
{
System_Out8(0x3DE,al);
if (al==ah) return(true);
al^=0xFF;
ah^=0xFF;
if (al==0x55 && ah==0x55) return(false);
}
}
//----------------------------------------------------------------------------------------------------
//модуль 2167
//----------------------------------------------------------------------------------------------------
void OAK_Unit2167(unsigned short addr,unsigned char v)
{
unsigned char ah;
ah=System_In8(addr);
System_Out8(addr,0x80);
System_Out8(0x102,0x01);
System_Out8(addr,ah);
System_Out8(0x3C3,v);
}
//----------------------------------------------------------------------------------------------------
//модуль 2148
//----------------------------------------------------------------------------------------------------
void OAK_Unit2148(unsigned char v)
{
System_Out8(0x46E8,0x17);
System_Out8(0x0102,System_In8(0x0102)|1);
System_Out8(0x46E8,v);
}
//----------------------------------------------------------------------------------------------------
//модуль 2A0F
//----------------------------------------------------------------------------------------------------
void OAK_Unit2A0F(void)
{
OAK_Unit28E2(0,8);
OAK_Unit28AC(0,0xBE);
OAK_Unit29E0();
OAK_Unit292D(0,0x11,0x06);
OAK_Unit292D(1,0x11,0x07);
OAK_Unit292D(2,0x06,0x1F);
OAK_Unit292D(3,0x06,0x15);
}
//----------------------------------------------------------------------------------------------------
//модуль 28E2
//----------------------------------------------------------------------------------------------------
void OAK_Unit28E2(unsigned char al,unsigned char ah)
{
unsigned char bl=al,bh=ah;
VGA_OutReg8(0x3DE,0x0D,VGA_InReg8(0x3DE,0x0D)|0x20);
System_Out8(0x3C7,0x0E);
al=System_In8(0x3C9)&bh;
ah^=0xFF;
bl&=ah;
bl|=al;
System_Out8(0x3C8,0x0E);
System_Out8(0x3C9,bl);
VGA_OutReg8(0x3DE,0x0D,VGA_InReg8(0x3DE,0x0D)&0xDF);
}
//----------------------------------------------------------------------------------------------------
//модуль 28AC
//----------------------------------------------------------------------------------------------------
void OAK_Unit28AC(unsigned char al,unsigned char ah)
{
unsigned char bl=al;
VGA_OutReg8(0x3DE,0x0D,VGA_InReg8(0x3DE,0x0D)|0x20);
al=System_In8(0x3C6)&ah;
ah^=0xFF;
bl&=ah;
al|=bl;
System_Out8(0x3C6,al);
VGA_OutReg8(0x3DE,0x0D,VGA_InReg8(0x3DE,0x0D)&0xDF);
}
//----------------------------------------------------------------------------------------------------
//модуль 29E0
//----------------------------------------------------------------------------------------------------
void OAK_Unit29E0(void)
{
if ((System_In8(0x3DE)&0xE0)==0xA0)
{
if (!(OAK_Unit1CED()&0x20)) OAK_Unit292D(0x0A,0x02,0x0C);
else OAK_Unit292D(0x0A,0x03,0x0D);
}
else OAK_Unit292D(0x0A,0x03,0x0D);
}
//----------------------------------------------------------------------------------------------------
//модуль 1CED
//----------------------------------------------------------------------------------------------------
unsigned char OAK_Unit1CED(void)
{
return((VGA_InReg8(0x3DE,0x10)&0x4F)|(VGA_InReg8(0x3DE,0x0B)&0xB0));
}
//----------------------------------------------------------------------------------------------------
//модуль 1E12
//----------------------------------------------------------------------------------------------------
void OAK_Unit1E12(void)
{
System_Out8(0x46E8,0x17);
System_Out8(0x0102,System_In8(0x0102)|1);
System_Out8(0x46E8,0x00);
}
//----------------------------------------------------------------------------------------------------
//модуль 292D
//----------------------------------------------------------------------------------------------------
void OAK_Unit292D(unsigned char al,unsigned char bl,unsigned char bh)
{
VGA_OutReg8(0x3DE,0x0D,VGA_InReg8(0x3DE,0x0D)|0x20);
System_Out8(0x3C8,al);
System_Out8(0x3C9,bh);
System_Out8(0x3C9,bl);
VGA_OutReg8(0x3DE,0x0D,VGA_InReg8(0x3DE,0x0D)&0xDF);
}