#include "complex.h" #include "pci.h" #include "dpmi.h" #include "screen.h" #define DEV_ID_VGA 0x30000 #define DEV_ID_AGP 0x60400 byte VBD_BUSNO_A; // AGP: Bus # byte VBD_DEVFN_A; // AGP: 7-3=device #, 2-0=function # byte VBD_BUSNO[4]; // Bus # byte VBD_DEVFN[4]; // 7-3=device #, 2-0=function # long VBD_EROM[4]; // Expansion ROM base address long VBD_ESIZE[4]; // Expansion ROM size in bytes word VBD_EINITS[4]; // EROM initialization address LMA long VBD_EBASE[4]; // Expansion ROM base address in low memory unsigned short VBD_CTL; // Control register (bridge only) AGP int actvga=0; //Астивный VGA extern int screen_run; //Екран с которого запущенно void EnVGA(int n_vga); //Включение VGA с номером n_vga dword initPCIvid() { int i = 0; unsigned char tmp_byte, *tmp_buf; unsigned int stat; unsigned short dev_index=0,dev_index_A=0,tmp_word,selector; __dpmi_regs d_regs; if(!pci_bios_available()) { while(!pci_class_code_find(dev_index,&stat,DEV_ID_VGA)) { VBD_DEVFN[dev_index]=stat&0xFF; VBD_BUSNO[dev_index]=(stat>>8)&0xFF; eprintf(GRAY_,"FOUND VGA %d (%d,%d) - OK",dev_index,VBD_BUSNO[dev_index],VBD_DEVFN[dev_index]); PCIReadConfRegWord(VBD_DEVFN[dev_index],VBD_BUSNO[dev_index],0x04,&tmp_word); if(tmp_word&0x03) screen_run=actvga=dev_index; PCIReadConfRegDword(VBD_DEVFN[dev_index],VBD_BUSNO[dev_index],0x30,&VBD_EROM[dev_index]); // Возьмём адрес expansion_rom VBD_EROM[dev_index]&=0xfffff800; eprintf(GRAY_,"EROM = %x tmp = %d",VBD_EROM[dev_index],tmp_word); dev_index++; } if(dev_index>1) { dev_index_A=0; while(!pci_class_code_find(dev_index_A,&stat,DEV_ID_AGP)) { VBD_DEVFN_A=stat&0xFF; VBD_BUSNO_A=(stat>>8)&0xFF; PCIReadConfRegByte(VBD_DEVFN_A,VBD_BUSNO_A,0x0e,&tmp_byte); // возьмём тип header if(tmp_byte==0x01) { PCIReadConfRegWord(VBD_DEVFN_A,VBD_BUSNO_A,0x3e,&VBD_CTL); //возьмём bridge control eprintf(GRAY_,"AGP = %d (%d,%d) VBD = %d - OK",dev_index,VBD_DEVFN_A,VBD_BUSNO_A,VBD_CTL); break; } dev_index_A++; } for(i=0;i>4,&selector,&VBD_EINITS[actvga]); VBD_EBASE[actvga]=VBD_EINITS[actvga]<<4; memcpy(VBD_EBASE[actvga],(char *)VBD_EROM[actvga],VBD_ESIZE[actvga]); tmp_buf=malloc(0x500); memcpy(tmp_buf,(char *)(0),0x500); //save IVT + BIOS DATA eprintf(GRAY_,"Save IVT"); d_regs.eax=VBD_BUSNO[actvga]; d_regs.eax<<=8; d_regs.eax=VBD_DEVFN[actvga]; d_regs.cs=VBD_EINITS[actvga]; d_regs.ip=0x03; eprintf(GRAY_,"Call init %d",i); dpmi_RM_proc_retf(&d_regs); memcpy((char *)(0),tmp_buf,0x500); free(tmp_buf); dpmi_dos_free(selector); dpmi_free_map_physical((char *)VBD_EROM[actvga]); eprintf(GRAY_,"OK %d",i); } EnVGA(0); } } return(dev_index); } //Включение VGA с номером n_vga void EnVGA(int n_vga) { unsigned short tmp_word; //-- DISABLE activ VGA -- if(VBD_BUSNO[actvga]==0x01) PCIWriteConfRegWord(VBD_DEVFN_A,VBD_BUSNO_A,0x3e,VBD_CTL&0xF7); //disable AGP VGA PCIReadConfRegWord(VBD_DEVFN[actvga],VBD_BUSNO[actvga],0x04, &tmp_word); PCIWriteConfRegWord(VBD_DEVFN[actvga],VBD_BUSNO[actvga],0x04,tmp_word&0xFC); //!! //-- Eneble VGA -- if(VBD_BUSNO[n_vga]==0x01) PCIWriteConfRegWord(VBD_DEVFN_A,VBD_BUSNO_A,0x3e,VBD_CTL|0x08); //enable AGP VGA PCIReadConfRegWord(VBD_DEVFN[n_vga],VBD_BUSNO[n_vga],0x04, &tmp_word); PCIWriteConfRegWord(VBD_DEVFN[n_vga],VBD_BUSNO[n_vga],0x04, tmp_word|0x03); //!! //Возможно необходимо востановить курсор actvga=n_vga; }