旧的ISA视频卡和AVR

大约十年前,我从286 ... 486台用于倾销的计算机上获得了ISA视频卡。 视频卡已经过测试,并且此后一直在抽屉中收集灰尘。 几年前,我有一个想法,但是我应该将这样的视频卡连接到微控制器吗? 这就是我将在本文中讨论的内容。

要连接旧的ISA视频卡,一条8位数据总线和一条20位地址总线就足够了。 微控制器我喜欢AVR系列产品的简单性,所以我选择了Atmega16。 但是您可以为您带来任何方便-在这种情况下,相同的stm32支脚肯定就足够了,而无需外部捆绑。 但是Atmega16没有足够的支脚来容纳所有这些总线,因此地址总线被组装在另外三个苏联并行寄存器(我有大量)K588IR1中。 微控制器依次在这三个寄存器中设置地址部分。 不需要更多。


在ISA连接器上,此电路的输出必须按以下方式连接:

+5,
+12,
地线
REFRESH(通过电阻上拉至+ 5V),
A0-A19,
D0-D7,
重设
Memw,
成员,
OW
IOR
麦酒
RDY,
AEN(连接到GND)。


在红色图片中,我标记了需要连接的ISA连接器引脚。

对于某些视频卡,您需要连接-5 V和-12 V(您必须将它们连接到某个地方-例如,从TracoPower电源获得)和OSC信号(14.318 MHz)-它可以由K155LN1上最简单的发生器生成。 其他图形卡不需要这些行。 这真幸运。 通常,如果ISA的相应脚悬在视频卡的空中,则绝对不能连接它。 请记住,视频卡在+ 5V线路上的功耗相当大-如果使用LM7805之类的电源,请确保将其放在散热器上(最好使用风扇)。

就我个人而言,我的组装设计如下所示:

图片

剩下的唯一事情就是以某种方式初始化视频卡并开始使用它。 互联网上有类似的项目-我找到了一个( 链接 ),在那里我获得了Trident 9000i视频卡的初始化代码。 在来自Internet的同一程序中,存在Trident9000C的初始化代码,但注释表明该代码无效。 我查了一下 它确实不起作用-屏幕上的垃圾和视频卡都没有响应将数据写入RAM。

工作视频(图片通过计算机的LPT端口通过SPI传输到了Atmega16(如右图所示,这些行在图中没有显示)):


(我在视频中进行了预定-320x200模式,而不是320x240)

通过将此模块与光电鼠标结合( 有关使用鼠标传感器的文章 ),我得到了以下信息:



如果您希望运行任何现有的ISA图形卡,则应该在Internet上找到所需图形卡的BIOS(例如, 此处 ),然后使用IDA对其进行拆卸。 有一个常规的X86代码。 它只是不从地址0开始-有一个签名(2个字节)和一个校验和(1个字节)。 总计,您需要从第3个字节开始。 并始终如一地找出您需要记录哪些端口以使卡工作。 坦白说,我没有耐心来了解Trident9000C出了什么问题。

为了使用ISA总线,编写了一个模块:

用于ISA总线的模块
//**************************************************************************************************** //       ISA //**************************************************************************************************** //**************************************************************************************************** // //**************************************************************************************************** //  #define ADDR_BUS_PORT PORTA #define ADDR_BUS_DDR DDRA //  A0-A7 #define ADDR_BUS_0_7_SELECT_PORT PORTC #define ADDR_BUS_0_7_SELECT_DDR DDRC #define ADDR_BUS_0_7_SELECT 7 //  A8-A15 #define ADDR_BUS_8_15_SELECT_PORT PORTC #define ADDR_BUS_8_15_SELECT_DDR DDRC #define ADDR_BUS_8_15_SELECT 6 //  A16-A19 #define ADDR_BUS_16_19_SELECT_PORT PORTC #define ADDR_BUS_16_19_SELECT_DDR DDRC #define ADDR_BUS_16_19_SELECT 5 //  #define DATA_BUS_PORT PORTB #define DATA_BUS_DDR DDRB #define DATA_BUS_PIN PINB //RESET #define RESET_DDR DDRD #define RESET_PORT PORTD #define RESET 0 //MEMW #define MEMW_DDR DDRD #define MEMW_PORT PORTD #define MEMW 1 //MEMR #define MEMR_DDR DDRD #define MEMR_PORT PORTD #define MEMR 2 //IOW #define IOW_DDR DDRD #define IOW_PORT PORTD #define IOW 3 //IOR #define IOR_DDR DDRD #define IOR_PORT PORTD #define IOR 4 //ALE #define ALE_DDR DDRD #define ALE_PORT PORTD #define ALE 5 //RDY #define RDY_DDR DDRD #define RDY_PORT PORTD #define RDY_PIN PIND #define RDY 6 //**************************************************************************************************** //  //**************************************************************************************************** void System_Init(void);//  void System_SetAddr(unsigned long addr);//    void System_RESET_HI(void);// RESET  1 void System_RESET_LO(void);// RESET  0 void System_MEMW_HI(void);// MEMW  1 void System_MEMW_LO(void);// MEMW  0 void System_MEMR_HI(void);// MEMR  1 void System_MEMR_LO(void);// MEMR  0 void System_IOW_HI(void);// IOW  1 void System_IOW_LO(void);// IOW  0 void System_IOR_HI(void);// IOR  1 void System_IOR_LO(void);// IOR  0 void System_ALE_HI(void);// ALE  1 void System_ALE_LO(void);// ALE  0 void System_WaitReady(void);//   void System_Out8(unsigned short port,unsigned char value);//    UInt8 void System_Out16(unsigned short port,unsigned short value);//    UInt16 unsigned char System_In8(unsigned short port);//    UInt8 unsigned short System_In16(unsigned short port);//    UInt16 void System_Poke8(unsigned long addr,unsigned char value);//    UInt8 void System_Poke16(unsigned long addr,unsigned short value);//    UInt16 unsigned char System_Peek8(unsigned long addr);//    UInt8 unsigned short System_Peek16(unsigned long addr);//    UInt16 //**************************************************************************************************** //  //**************************************************************************************************** //---------------------------------------------------------------------------------------------------- //  //---------------------------------------------------------------------------------------------------- void System_Init(void) { //  DDRA=0; DDRB=0; DDRD=0; DDRC=0; ADDR_BUS_DDR=0xff; DATA_BUS_DDR=0; ADDR_BUS_0_7_SELECT_DDR|=(1<<ADDR_BUS_0_7_SELECT); ADDR_BUS_8_15_SELECT_DDR|=(1<<ADDR_BUS_8_15_SELECT); ADDR_BUS_16_19_SELECT_DDR|=(1<<ADDR_BUS_16_19_SELECT); RESET_DDR|=(1<<RESET); MEMW_DDR|=(1<<MEMW); MEMR_DDR|=(1<<MEMR); IOW_DDR|=(1<<IOW); IOR_DDR|=(1<<IOR); ALE_DDR|=(1<<ALE); RDY_DDR&=0xff^(1<<RDY); RDY_PORT|=1<<RDY; //   asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_0_7_SELECT_PORT)),[bit]"M"(ADDR_BUS_0_7_SELECT)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_8_15_SELECT_PORT)),[bit]"M"(ADDR_BUS_8_15_SELECT)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_16_19_SELECT_PORT)),[bit]"M"(ADDR_BUS_16_19_SELECT)); asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(RESET_PORT)),[bit]"M"(RESET)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(IOW_PORT)),[bit]"M"(IOW)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(IOR_PORT)),[bit]"M"(IOR)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(MEMW_PORT)),[bit]"M"(MEMW)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(MEMR_PORT)),[bit]"M"(MEMR)); asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ALE_PORT)),[bit]"M"(ALE)); } //---------------------------------------------------------------------------------------------------- //    //---------------------------------------------------------------------------------------------------- void System_SetAddr(unsigned long addr) { unsigned char al=addr&0xff; unsigned char am=(addr>>8)&0xff; unsigned char ah=(addr>>16)&0xff; System_ALE_LO();//  ALE //     ADDR_BUS_PORT=ah; asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_16_19_SELECT_PORT)),[bit]"M"(ADDR_BUS_16_19_SELECT)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_16_19_SELECT_PORT)),[bit]"M"(ADDR_BUS_16_19_SELECT)); ADDR_BUS_PORT=am; asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_8_15_SELECT_PORT)),[bit]"M"(ADDR_BUS_8_15_SELECT)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_8_15_SELECT_PORT)),[bit]"M"(ADDR_BUS_8_15_SELECT)); ADDR_BUS_PORT=al; asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_0_7_SELECT_PORT)),[bit]"M"(ADDR_BUS_0_7_SELECT)); asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ADDR_BUS_0_7_SELECT_PORT)),[bit]"M"(ADDR_BUS_0_7_SELECT)); System_ALE_HI();//  ALE } //---------------------------------------------------------------------------------------------------- // RESET  1 //---------------------------------------------------------------------------------------------------- inline void System_RESET_HI(void) { asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(RESET_PORT)),[bit]"M"(RESET)); } //---------------------------------------------------------------------------------------------------- // RESET  0 //---------------------------------------------------------------------------------------------------- inline void System_RESET_LO(void) { asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(RESET_PORT)),[bit]"M"(RESET)); } //---------------------------------------------------------------------------------------------------- // MEMW  1 //---------------------------------------------------------------------------------------------------- inline void System_MEMW_HI(void) { asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(MEMW_PORT)),[bit]"M"(MEMW)); } //---------------------------------------------------------------------------------------------------- // MEMW  0 //---------------------------------------------------------------------------------------------------- inline void System_MEMW_LO(void) { asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(MEMW_PORT)),[bit]"M"(MEMW)); } //---------------------------------------------------------------------------------------------------- // MEMR  1 //---------------------------------------------------------------------------------------------------- inline void System_MEMR_HI(void) { asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(MEMR_PORT)),[bit]"M"(MEMR)); } //---------------------------------------------------------------------------------------------------- // MEMR  0 //---------------------------------------------------------------------------------------------------- inline void System_MEMR_LO(void) { asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(MEMR_PORT)),[bit]"M"(MEMR)); } //---------------------------------------------------------------------------------------------------- // IOW  1 //---------------------------------------------------------------------------------------------------- inline void System_IOW_HI(void) { asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(IOW_PORT)),[bit]"M"(IOW)); } //---------------------------------------------------------------------------------------------------- // IOW  0 //---------------------------------------------------------------------------------------------------- inline void System_IOW_LO(void) { asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(IOW_PORT)),[bit]"M"(IOW)); } //---------------------------------------------------------------------------------------------------- // IOR  1 //---------------------------------------------------------------------------------------------------- inline void System_IOR_HI(void) { asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(IOR_PORT)),[bit]"M"(IOR)); } //---------------------------------------------------------------------------------------------------- // IOR  0 //---------------------------------------------------------------------------------------------------- inline void System_IOR_LO(void) { asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(IOR_PORT)),[bit]"M"(IOR)); } //---------------------------------------------------------------------------------------------------- // ALE  1 //---------------------------------------------------------------------------------------------------- inline void System_ALE_HI(void) { asm volatile ("sbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ALE_PORT)),[bit]"M"(ALE)); } //---------------------------------------------------------------------------------------------------- // ALE  0 //---------------------------------------------------------------------------------------------------- inline void System_ALE_LO(void) { asm volatile ("cbi %[port],%[bit]"::[port]"I"(_SFR_IO_ADDR(ALE_PORT)),[bit]"M"(ALE)); } //---------------------------------------------------------------------------------------------------- //   //---------------------------------------------------------------------------------------------------- void System_WaitReady(void) { asm volatile ("nop"::); asm volatile ("nop"::); while(1) { if (RDY_PIN&(1<<RDY)) break; } } //---------------------------------------------------------------------------------------------------- //    UInt8 //---------------------------------------------------------------------------------------------------- void System_Out8(unsigned short port,unsigned char value) { //     DATA_BUS_DDR=0xff; DATA_BUS_PORT=value; System_SetAddr(port); //   System_IOW_LO(); System_WaitReady();//  System_IOW_HI(); DATA_BUS_DDR=0; } //---------------------------------------------------------------------------------------------------- //    UInt16 //---------------------------------------------------------------------------------------------------- void System_Out16(unsigned short port,unsigned short value) { System_Out8(port,value&0xff); System_Out8(port+1,(value>>8)&0xff); } //---------------------------------------------------------------------------------------------------- //    UInt8 //---------------------------------------------------------------------------------------------------- unsigned char System_In8(unsigned short port) { unsigned char byte; System_SetAddr(port); DATA_BUS_DDR=0; //   System_IOR_LO(); System_WaitReady();//  byte=DATA_BUS_PIN; System_IOR_HI(); return(byte); } //---------------------------------------------------------------------------------------------------- //    UInt16 //---------------------------------------------------------------------------------------------------- unsigned short System_In16(unsigned short port) { unsigned short ret=System_In8(port+1); ret<<=8; ret|=System_In8(port); return(ret); } //---------------------------------------------------------------------------------------------------- //    UInt8 //---------------------------------------------------------------------------------------------------- void System_Poke8(unsigned long addr,unsigned char value) { //     DATA_BUS_DDR=0xff; DATA_BUS_PORT=value; System_SetAddr(addr); //   System_MEMW_LO(); System_WaitReady();//  System_MEMW_HI(); DATA_BUS_DDR=0; } //---------------------------------------------------------------------------------------------------- //    UInt16 //---------------------------------------------------------------------------------------------------- void System_Poke16(unsigned long addr,unsigned short value) { System_Poke8(addr,value&0xff); System_Poke8(addr+1,(value>>8)&0xff); } //---------------------------------------------------------------------------------------------------- //    UInt8 //---------------------------------------------------------------------------------------------------- unsigned char System_Peek8(unsigned long addr) { unsigned char byte; System_SetAddr(addr); DATA_BUS_DDR=0; //   System_MEMR_LO(); System_WaitReady();//  byte=DATA_BUS_PIN; System_MEMR_HI(); return(byte); } //---------------------------------------------------------------------------------------------------- //    UInt16 //---------------------------------------------------------------------------------------------------- unsigned short System_Peek16(unsigned long addr) { unsigned short ret=System_Peek8(addr+1); ret<<=8; ret|=System_Peek8(addr); return(ret); } 


Trident 9000i图形卡的初始化如下:

初始化Trident 9000i图形
 //**************************************************************************************************** //     trident //**************************************************************************************************** //**************************************************************************************************** // //**************************************************************************************************** //**************************************************************************************************** //  //**************************************************************************************************** CHIP_TYPE TRIDENT_Init(void);//   Trident unsigned char TRIDENT_TestInx2(unsigned short rg,unsigned char ix,unsigned char msk);// true,   MSK  PT   RG  1 void TRIDENT_TR9000i_Init(void);//  Trident9000i void TRIDENT_TR8900D_Init(void);//  Trident8900D bool TRIDENT_Unit_594(void);// 594 void TRIDENT_Unit_5A6(void);// 5A6 bool TRIDENT_Unit_4D9(void);// 4D9 void TRIDENT_Unit_51A(void);// 51A unsigned char TRIDENT_Unit_26A(void);// 26A void TRIDENT_Unit_179(void);// 179 void TRIDENT_Unit_2EA(void);// 2EA unsigned char TRIDENT_Unit_292(void);// 292 //**************************************************************************************************** //  //**************************************************************************************************** //---------------------------------------------------------------------------------------------------- //   Trident //---------------------------------------------------------------------------------------------------- CHIP_TYPE TRIDENT_Init(void) { VGA_Reset();//   CHIP_TYPE chiptype=UNKNOWN;//     //Trident VGA (  8800BR)    2 : // ,   128k,      A000h - BFFFh //     64k,     A000h - AFFFh. System_Out8(VGAENABLE_ADDR,0x00); System_Out8(0x46E8,0x16);//    (D3=0) System_Out8(0x46E9,0x00); System_Out8(0x0102,0x01); System_Out8(0x0103,0x00); System_Out8(0x46E8,0x0E);//    (D3=1) System_Out8(0x46E9,0x00); System_Out8(0x4AE8,0x00); System_Out8(0x4AE9,0x00); VGA_OutReg8(SEQ_ADDR,0x0B,0x00);//  ID    unsigned char chip=System_In8(0x3C5);//    unsigned char old=VGA_InReg8(SEQ_ADDR,0x0E); System_Out8(0x3C5,0x00); unsigned char value=System_In8(0x3C5)&0x0F; System_Out8(0x3C5,old); //   if (value==2) { System_Out8(0x3C5,old^2); switch(chip) { case 0x01: chiptype=TR8800BR; break; case 0x02: chiptype=TR8800CS; break; case 0x03: chiptype=TR8900; break; case 0x04: chiptype=TR8900C; TRIDENT_TR8900D_Init(); break; case 0x13: chiptype=TR8900C; TRIDENT_TR8900D_Init(); break; case 0x23: chiptype=TR9000; TRIDENT_TR9000i_Init(); break; case 0x33: chiptype=TR8900CLD; TRIDENT_TR8900D_Init(); break; case 0x43: chiptype=TR9000i; TRIDENT_TR9000i_Init(); break; case 0x53: chiptype=TR8900CXr; break; case 0x63: chiptype=LCD9100B; break; case 0x83: chiptype=LX8200; break; case 0x93: chiptype=TVGA9400CXi; break; case 0xA3: chiptype=LCD9320; break; case 0x73: chiptype=GUI9420; break; case 0xF3: chiptype=GUI9420; break; } } else { if ((chip==1)&TRIDENT_TestInx2(SEQ_ADDR,0x0E,6)) chiptype=TVGA8800BR; } return(chiptype); } //---------------------------------------------------------------------------------------------------- // true,   MSK  PT   RG  1 //---------------------------------------------------------------------------------------------------- unsigned char TRIDENT_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); return((nw1==0)&(nw2==msk)); } //---------------------------------------------------------------------------------------------------- //  Trident9000i //---------------------------------------------------------------------------------------------------- void TRIDENT_TR9000i_Init(void) { unsigned short i=0; System_Out8(VGAENABLE_ADDR,0x00); if (TRIDENT_Unit_4D9()==false) return;// do { System_Out8(0x3C9,0x00); i++; } while (i<768); System_Out8(MISC_ADDR,0x23); TRIDENT_Unit_51A(); } //---------------------------------------------------------------------------------------------------- //  Trident8900D //---------------------------------------------------------------------------------------------------- void TRIDENT_TR8900D_Init(void) { if (TRIDENT_Unit_594()==true) { //  256  System_Out8(0x3C8,0x00); for(unsigned short n=0;n<256;n++) { System_Out8(0x3C9,n);//R System_Out8(0x3C9,0);//G System_Out8(0x3C9,0);//B } System_Out8(MISC_ADDR,0x23); TRIDENT_Unit_5A6(); } if (TRIDENT_Unit_594()==false) { System_In8(STATUS_ADDR); System_Out8(ATTRCON_ADDR,0x20); System_In8(STATUS_ADDR); VGA_OutReg8(CRTC_ADDR,0x020,VGA_InReg8(CRTC_ADDR,0x20)&0xDF); } System_Out8(0x3D8,0x00); VGA_OutReg8(CRTC_ADDR,0x23,0x10); System_Out8(0x3C6,0xff); } //---------------------------------------------------------------------------------------------------- // 594 //---------------------------------------------------------------------------------------------------- bool TRIDENT_Unit_594(void) { VGA_OutReg8(SEQ_ADDR,0x0B,0x00);//   if ((VGA_InReg8(SEQ_ADDR,0x0D)&0x0E)!=0x0C) return(true); if ((System_In8(0x3CC)&0x67)!=0x67) return(true); return(false); } //---------------------------------------------------------------------------------------------------- // 5A6 //---------------------------------------------------------------------------------------------------- void TRIDENT_Unit_5A6(void) { unsigned char al,bh; VGA_InReg8(SEQ_ADDR,0x0B);//   VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)|0x80)^2); bh=(VGA_InReg8(SEQ_ADDR,0x0C)&0xFE)|0x80; if (VGA_InReg8(SEQ_ADDR,0x0B)==0x53)//   { VGA_InReg8(CRTC_ADDR,0x29); VGA_OutReg8(CRTC_ADDR,0x29,0x44); VGA_OutReg8(CRTC_ADDR,0x2B,0x03); VGA_OutReg8(CRTC_ADDR,0x2C,0x3D); VGA_OutReg8(CRTC_ADDR,0x25,0x27); } if (!(!VGA_InReg8(CRTC_ADDR,0x28)&1)) { bh&=0xCE; bh|=0x80; VGA_OutReg8(MISC_ADDR,0x01,0x00);//  0x3D2 (  0x01) al=(VGA_InReg8(CRTC_ADDR,0x28))&0x0C; if (al==0) { al|=0x04; VGA_OutReg8(CRTC_ADDR,0x28,al); } VGA_OutReg8(SEQ_ADDR,0x0F,VGA_InReg8(SEQ_ADDR,0x0F)&0x7F); VGA_InReg8(SEQ_ADDR,0x0C); VGA_OutReg8(SEQ_ADDR,0x0C,bh); VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)&0x7F)^2); if (VGA_InReg8(SEQ_ADDR,0x0F)&0x08) { VGA_InReg8(SEQ_ADDR,0x0B);//   VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)|0x80)^2); al=(VGA_InReg8(SEQ_ADDR,0x0C)&0xFE)|0x80; al&=0xFE; VGA_OutReg8(SEQ_ADDR,0x0C,al); VGA_OutReg8(GRACON_ADDR,0x0F,0x00); al=VGA_InReg8(SEQ_ADDR,0x0C);//  VGA_OutReg8(SEQ_ADDR,0x0F,VGA_InReg8(SEQ_ADDR,0x0F)|0x80); VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)&0x7F)^0x02); } } VGA_OutReg8(SEQ_ADDR,0x0B,0x00);//  VGA_OutReg8(SEQ_ADDR,0x0D,0x20); VGA_OutReg8(SEQ_ADDR,0x0E,0xA0); VGA_InReg8(SEQ_ADDR,0x0B);//   VGA_OutReg8(SEQ_ADDR,0x0E,0x02); al=VGA_InReg8(GRACON_ADDR,0x06);//atvizsglni if (al==0) { al&=0xF3; al|=0x04; VGA_OutReg8(GRACON_ADDR,0x06,al); } VGA_OutReg8(SEQ_ADDR,0x0D,0x00); VGA_InReg8(CRTC_ADDR,0x1E); VGA_OutReg8(CRTC_ADDR,0x1E,0x00); if (VGA_InReg8(SEQ_ADDR,0x0B)==0x53) VGA_OutReg8(CRTC_ADDR,0x20,0x1D);//   else VGA_OutReg8(CRTC_ADDR,0x20,0x1C); VGA_OutReg8(CRTC_ADDR,0x29,0x44); } //---------------------------------------------------------------------------------------------------- // 4D9 //---------------------------------------------------------------------------------------------------- bool TRIDENT_Unit_4D9(void) { unsigned char al; al=TRIDENT_Unit_292()&0x0E; if (al!=0x0C) return(true); al=System_In8(0x3CC)&0x67; if (al!=0x67) return(true); return(false); } //---------------------------------------------------------------------------------------------------- // 51A //---------------------------------------------------------------------------------------------------- void TRIDENT_Unit_51A(void) { unsigned char al,bh; bh=(TRIDENT_Unit_26A()|0x80)&0xFE; VGA_OutReg8(SEQ_ADDR,0x07,0x24); System_Out8(MISC_ADDR,0x01); if (!((al=VGA_InReg8(CRTC_ADDR,0x28))&0x0C)) { al|=0x04; VGA_OutReg8(CRTC_ADDR,0x28,al); } VGA_OutReg8(SEQ_ADDR,0x0F,VGA_InReg8(SEQ_ADDR,0x0F)&0x7F); VGA_OutReg8(SEQ_ADDR,0x0C,bh); VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)&0x7F)^2); if (VGA_InReg8(SEQ_ADDR,0x0F)&0x08) TRIDENT_Unit_179(); TRIDENT_Unit_2EA();//  VGA_OutReg8(SEQ_ADDR,0x0D,0x20); VGA_OutReg8(SEQ_ADDR,0x0E,0xA0); VGA_InReg8(SEQ_ADDR,0x0B);//  VGA_OutReg8(SEQ_ADDR,0x0E,0x02); if (!((al=VGA_InReg8(GRACON_ADDR,0x06))&0x0C)) VGA_OutReg8(GRACON_ADDR,0x06,(al&0xF3)|0x04); VGA_OutReg8(SEQ_ADDR,0x0D,0x00); al=VGA_InReg8(CRTC_ADDR,0x1E); VGA_OutReg8(CRTC_ADDR,0x1E,0x00); } //---------------------------------------------------------------------------------------------------- // 26A //---------------------------------------------------------------------------------------------------- unsigned char TRIDENT_Unit_26A(void) { VGA_InReg8(SEQ_ADDR,0x0B);//   VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)|0x80)^2); return(VGA_InReg8(SEQ_ADDR,0x0C)); } //---------------------------------------------------------------------------------------------------- // 179 //---------------------------------------------------------------------------------------------------- void TRIDENT_Unit_179(void) { // SP  BP VGA_OutReg8(SEQ_ADDR,0x0C,(TRIDENT_Unit_26A()|0x42)&0xFE); VGA_OutReg8(SEQ_ADDR,0x0F,VGA_InReg8(SEQ_ADDR,0x0F)|0x80); VGA_OutReg8(SEQ_ADDR,0x0E,(VGA_InReg8(SEQ_ADDR,0x0E)&0x7F)^2); } //---------------------------------------------------------------------------------------------------- // 2EA //---------------------------------------------------------------------------------------------------- void TRIDENT_Unit_2EA(void) { VGA_OutReg8(SEQ_ADDR,0x0B,0x00);//   } //---------------------------------------------------------------------------------------------------- // 292 //---------------------------------------------------------------------------------------------------- unsigned char TRIDENT_Unit_292(void) { TRIDENT_Unit_2EA();//   return(VGA_InReg8(SEQ_ADDR,0x0D));// ,  SEQ_ADDR 0x0D } 


我还启动了OAK OTI077视频卡(直到我不小心对其施加了12 V电压,然后烧坏了):

OAK OTI077图形卡的初始化
 //**************************************************************************************************** //     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); } 


顺便说一下,这里有VGA适配器寄存器方面的专家吗? 初始化视频卡时,我在视频模式更改代码中看到奇怪的事情:

 //   #define ATTRCON_ADDR 0x03C0 System_In8(0x03DA); System_Out8(ATTRCON_ADDR,0x20); 

通常,这里没有什么特别的。 写入属性控制器的寄存器分两个步骤:首先写入寄存器号,然后写入数据。 要始终从记录数字开始,请阅读ISR1(从0x03DA开始)-就是这样。

但这是奇怪的事情。 属性控制器没有0x20寄存器! 他的最后一个寄存器为0x14。 即使会有这样的寄存器,为什么没有价值记录呢? 端口中应该有两个条目。 在这里,她一个人。 我搜索了互联网,发现由于某种原因(在书中我没有找到这个),您可以简单地通过组合以下位,一次在0x10寄存器中写入值0x20:System_Out8(ATTRCON_ADDR,0x10 | 0x20); 然后,指定的记录将0x20写入寄存器0x00? 但是为什么这样做呢? 是这样吗? 这对我来说很有趣,这就是为什么-整个问题是,初始化后有时候颜色会掉下来。 调色板没有设置。 可以看出它正在变化,但是颜色根本不应该是它们应该的颜色。 如果再次进行初始化,则将恢复所有内容。 目前尚不清楚在什么阶段发生。 通过实验,我发现很有可能这只是视频模式的安装。 但是我不明白到底是什么。

→通过印刷电路板链接到档案
→使用固件链接到档案

Source: https://habr.com/ru/post/zh-CN406193/


All Articles