显存读写

您所在的位置:网站首页 保护模式显存地址怎么设置 显存读写

显存读写

2023-07-06 15:33| 来源: 网络整理| 查看: 265

        要在显示屏显示图像,方法有两种,mmio pio。现在的显卡都应当支持vbe。

         vbe 提供了保护模式的接口,bios方式太旧了,且保护模式操作太复杂,故想找个简单的方式,但这方面的资料太少,花了不少时间,终于成功。

         利用bios 10号中断取得保护接口信息,除5、7、9号程序,还有几个端口信息,好不容易找到保护模式切换显示模式的使用方法。不过还不确定bios返回端口的具体用途,但显示设置的函数实验成功。

        显存的访问,在低分辨率及字符模式,地址在0xa0000---0xbffff之间,但到了高分辨率就一般在高端内存。网上查的说可以直接访问,我怎么实验都没成功。搞了一个星期,终于可以正确显示。

      要想访问显存,有3步:

     1. 显存的物理地址,英文叫LFB,可以bios 1号中段获取,资料上说可以自主设置,不过我在bochs上没成功,不知哪里出错了,后来没搞了。

      2. MTRR,说起来有点复杂,意思就是把显存地址注册到地址空间。独显、核显、仿真对地址分配有没区别,还待实验。

      3. 显卡设置,开启lfb。好象只能显示真彩色,低色彩的还没成功。

    开启之后,就显存地址就是物理地址了,统一在4G之内,读写也正常,屏幕显示正常,不过bochs显示内存指令不能显示,不知道是bochs的问题,还是本来就这样。关键代码在下面

void BgaSetVideoMode(unsigned int Width, unsigned int Height, unsigned int BitDepth, int UseLinearFrameBuffer, int ClearVideoMemory) {     // VBE disabling     BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_DISABLED);     //     BgaWriteRegister(VBE_DISPI_INDEX_XRES, Width);     BgaWriteRegister(VBE_DISPI_INDEX_YRES, Height);     BgaWriteRegister(VBE_DISPI_INDEX_BPP, BitDepth);     BgaWriteRegister(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED |         (UseLinearFrameBuffer ? VBE_DISPI_LFB_ENABLED : 0) |         (ClearVideoMemory ? 0 : VBE_DISPI_NOCLEARMEM)); }

 

DWORD find_empty_mtrr() {              //RDMSR将64位由ECX寄存器指定的MSR(model specific register,         //模式指定寄存器)的内容读出至寄存器EDX:EAX中         //(在支持intel64架构的处理器中RCX的高32位忽略)。         //MSR的高32位内容存放在EDX寄存器中,         //MSR的低32位内容存放在EAX寄存器中         //(在支持intel64架构的处理器中RDX和RAX的高32位忽略)。         //如果MSR中没有64位(有些位没有实现),         //则EDX:EAX中没有实现的位置则未定义。         //寄存器2个一组         DWORD empmtrr,port,val1,val2;         empmtrr=0;         for (port=0x201;port                 port--;                 empmtrr=port;                 break;             }         }         return empmtrr; } void enableMtrr(DWORD addr) {

    DWORD mttr,val1,val2;     mttr = find_empty_mtrr();     // ; LFB , +8 M , write combine     //|64 保留    | 物理地址 12|11  8|7 type |0     //|64 保留    | 掩码|Valid 11|10 保留 |0         wrmsr(mttr,addr | 1,0);          wrmsr(mttr+1,0xff800800,0xf);  //     enable mtrr's     rdmsr(0x2ff,val1,val2);       wrmsr(0x2ff,val1 | 0x800 ,val2);                }

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3