关于显存地址问题

转自:http://hi.baidu.com/xylemily/blog/item/0293a18c0cf283e2f11f3667.html

为什么有些书说显存首地址为A00000,有的说再B8000?

显示模式不同。 
我记得B800是单色 
A000是彩色(图形?)

我想你是在dos下编写吧:) 
不同的显示模式首地址不一样 
a000000l通常是0X13 
b8000那是文本模式

如果是DOS下编,注意以下几点: 

1。所有图形方式中显示缓冲区起始地址都是 A000:0000,即 0xA0000000 
2。如果程序工作在保护模式,则起址应为 0xA0000; 
3。显示缓冲区长度永远为 0xFFFF 字节。 
4。0x13h 以上的图形模式中,超出的字节应通过切换显示页(其实就是显卡上显存中的 
起始指针)实现。 
5。直接颜色模式和间接颜色模式对内存的组织是不同的。  

1.b800:0000是文本模式(如3模式)显存起始地址 
2.13模式以上通过修改显卡某个寄存器做页面切换。

Windows下不能直接访问显存,最接近的方法就是DirectX。

怎么样才能直接读取显存的内容?? 是用DirectX的DirectShow?还是Direct Draw?怎么用呢?那个函数? 
有没有API可以直接杜显存的?你去看看《深入 DirectX7.0 》,里面有详细介绍! 
或者看MSDN,DirectX是专门对硬件编程的!

用DirectDraw,创建PrimarySurface,然后Lock之,就可以得到显存地址,读写完后再Unlock()。具体的有点复杂,一句两句说不清,最好看书或参考MSDN。 
算了,还是给你代码吧。 
//初始化 
HRESULT hRet = DirectDrawCreateEx( NULL, (VOID**)&m_pDirectDraw, IID_IDirectDraw7, NULL ); 

if(hRet != DD_OK) 

OUTPUT_ERROR( hRet ); 
THROW( ERR_DIRECTDRAWINITFAILED ); 
return; 


// Step 2: Set the cooperative level 
hRet = m_pDirectDraw->SetCooperativeLevel(hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); 
// Step 3:Set display mode 
hRet = m_pDirectDraw->SetDisplayMode( GAMERES_X, GAMERES_Y, GAMECOLORBITDEPTH, 0, 0 ); 

// Step 4: Create a primary surface with one backsurface 
DDSURFACEDESC2 ddsd; 

ZeroMemory( &ddsd, sizeof(ddsd)); 
ddsd.dwSize = sizeof(ddsd); 
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; 
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; 
ddsd.dwBackBufferCount = 1; 
hRet = m_pDirectDraw->CreateSurface( &ddsd, &m_pDDSPrimary, NULL ); 

//lock 
DDSURFACEDESC2 ddsdPrimary; 
ddsdPrimary.dwSize = sizeof(DDSURFACEDESC2); 

hRes = m_pDDSPrimary->Lock( NULL, &ddsdPrimary, DDLOCK_WAIT, DDLOCK_NOSYSLOCK, 0 ); 

LPBYTE lpbyMemory = (LPBYTE)ddsdPrimary.lpSurface; 
// do some thing 
// Unlock 
m_pDDSPrimary->Unlock(NULL);

书上说,内存地址A000:0000到B000:0000为显示存储器,共128KB,C000:0000到FFFF:FFFF为各种BIOS用。有的书又说EGA/VGA卡中由256KB的动态存储器(DRAM)组成,扩展的Super VGA显示系统中,显示存储器大多超过256KB,高达512kB或1MB或更高。 
请问显存到底在系统内存上还是显卡上,那大于128KB的显存在哪儿,地址又是多少。Windows下也把内存地址A000:0000到B000:0000为显示存储器吗?

显存当然是在显卡上了,为了能对现存进行操作,将系统的内存进行映射,所以写到这些内存里就象是写到了显存里一样,不同的显卡映射地址不一样,与操作系统无关。

既然是映射,那写到这个内存中就相当于写到显存中罗,这与内存中有什么好象没关系吧。关于这个映射好象是vga卡在每次回扫时扫描这段内存将数据变成视频信号输出

大于128KB的显存在显卡上,地址还是使用A000:0000(DOS下, WINDOWS 9x里已经实现显存动态定位了)至于如何切换需要操作显卡上的位屏蔽寄存器来实现,具体可是参考VESA标准. 
为了兼容,WINDOWS当然要把A000:0000到B000:0000作为显示存储器地址之一

你可能感兴趣的:(C/C++)