zhenlongyang
驱动小牛
驱动小牛
  • 注册日期2004-10-28
  • 最后登录2010-07-26
  • 粉丝1
  • 关注0
  • 积分729分
  • 威望100点
  • 贡献值0点
  • 好评度66点
  • 原创分0分
  • 专家分0分
阅读:2148回复:6

急救!哪位专家知道如何通过直接端口操作或VESA中断调用修改显示器刷新批率请不吝赐教,不胜感激!顷囊相增!

楼主#
更多 发布于:2004-10-30 21:44
由于工作需要,我需要开发一个直接控制显示卡(符合VESA标准)绘图的图形库,万事具备就只差一个控制显示器刷新频率的功能未能实现,致使图形画面闪烁严重,虽然从VESA的官方网站上下载了一个VBE3.0标准,但是E文水平有限不能完全理解其精髓致使该功能一直无法实现,真是头疼!如果有那位仁兄有这方面的编程经验或能提供一些中文资料本人将不胜感激,若能实现本功能,本人将会把所有的可用分顷囊相增!拜托!拜托!
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-10-30 22:22
参考一下
《最新VESA SVGA 图形图像编程秘技》应该对你有帮助
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
zhenlongyang
驱动小牛
驱动小牛
  • 注册日期2004-10-28
  • 最后登录2010-07-26
  • 粉丝1
  • 关注0
  • 积分729分
  • 威望100点
  • 贡献值0点
  • 好评度66点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-10-31 02:09
先谢了,不过哪能找到这本书呢?最好是电子版的,我去过好几个大书店,都没有,麻烦帮忙找一下啦,非常感谢。
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-11-10 20:52
先谢了,不过哪能找到这本书呢?最好是电子版的,我去过好几个大书店,都没有,麻烦帮忙找一下啦,非常感谢。


直接看VBE就好了。昨天发邮件给你了。摘抄一段:

今天抽空看了一下VESA BIOS EXTENSION (VBE) Core Functions Standard, 发现里面确实有设置Refresh rate的地方。我的笔记本没办法调试,把大致的想法和你说一下,你先看一下,有问题欢迎讨论。

1. 在Funciton 02h - Set VBE Mode的描述如下:
Input: AX = 4F02h Set VBE Mode
       BX = Desired Mode to set
            D0-D8  = Mode number
            D9-D10 = Reserved (must be 0)
            D11    = 0 Use current default refresh rate
                   = 1 Use user specified CRTC values for refresh rate
            D12-13   Reserved for VBE/AF (must be 0)
            D14    = 0 Use windowed frame buffer model
                   = 1 Use linear/flat frame buffer model
            D15    = 0 Clear display memory
                   = 1 Don't clear display memory
       ES:DI = Pointer to CRTCInfoBlock structure
Output: AX = VBE Return Status
实际上如果在DOS下想得到高的图像品质,一定会调用这个Function的。比如我以前做的DOS下SVGA显示,800*600*16bit色的初始化程序片断如下:
// Init to 800*600*16bit graphics mode:
    union REGS in, out;
    iMode=0x114;
in.x.bx=iMode;
in.x.ax=0x4F02;
int86(0x10,&in,&out);
在这个程序片断中,bx=0x114
0000 0001 0001 0100
如果把D15改成1,就可以用ES:DI指向的结构里的一个元素来更改refresh rate了。

CRTCInfoBlock struc
HorizontalTotal dw ? ; Horizontal total in pixels
HorizontalSyncStart dw ? ; Horizontal sync start in pixels
HorizontalSyncEnd dw ? ; Horizontal sync end in pixels
VerticalTotal dw ? ; Vertical total in lines
VerticalSyncStart dw ? ; Vertical sync start in lines
VerticalSyncEnd dw ? ; Vertical sync end in lines
Flags db ? ; Flags (Interlaced, Double Scan etc)
PixelClock dd ? ; Pixel clock in units of Hz
RefreshRate dw ? ; Refresh rate in units of 0.01 Hz
Reserved db 40 dup (?) ; remainder of ModeInfoBlock
CRTCInfoBlock ends

Attatched please find the VBE pdf file, and the cpp file for example.
I believe you'd already get these files, and maybe you should modify
the initial graph part, then try it.
助人乃快乐之本 有人给分就更快乐了 :-)
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-11-12 14:50
搞定了。还真有点难,花了俺大概5个Hour...好久没编程了(最近都是让手下编),忽然自己编,有点累哦。  :D

问题的关键是,VBE上有些事没有说清楚。建议先去搞清楚屏幕上几种显示的关系(HTotal / HSyncStart / HSyncEnd / VTotal / VSyncStart / VSyncEnd),
http://www.hut.fi/Misc/Electronics/faq/vga2rgb/timings.html
然后再去这里算一下你相应的分辩率与更新率下的相应数字,
http://www.hut.fi/Misc/Electronics/faq/vga2rgb/calc.html
就可以开工了。

例子程序中的关键代码及注释:
// SuperVGA CRTCInfoBlock structure
struct
{
	short HTotal;
	short HSyncStart;
	short HSyncEnd;
	short VTotal;
	short VSyncStart;
	short VSyncEnd;
	char Flags;
	long PixelClock;
	short RefreshRate;
	char Reserved[40];
} CRTCInfoBlock;

很简单,就是按VBE中所说的做了个结构。

void setVBEMode(int mode)
{
	union REGS in,out;
	struct SREGS segs;
	char far *CRTCInfo;

	in.x.ax = 0x4F02;
	//in.x.bx = mode;
	in.x.bx = 0x905;	// --------------------- Note 1

	// 1024*768 @ 70Hz
	CRTCInfoBlock.HTotal=1328;
	CRTCInfoBlock.HSyncStart=1048;
	CRTCInfoBlock.HSyncEnd=1184;
	CRTCInfoBlock.VTotal=806;
	CRTCInfoBlock.VSyncStart=771;
	CRTCInfoBlock.VSyncEnd=777;
	CRTCInfoBlock.Flags=0xa;   // -------------- Note 2
	CRTCInfoBlock.PixelClock=75000000;
	CRTCInfoBlock.RefreshRate=70.07;
	CRTCInfo = (char far *)&CRTCInfoBlock;
	// ----------------------------------------- Note 3
	in.x.di = FP_OFF(CRTCInfo);
	segs.es = FP_SEG(CRTCInfo);
	int86x(0x10, &in, &out, &segs);
	//int86(0x10,&in,&out);
}


Note 1: 我跟踪调试,如果不自己设置Refresh rate,这里imode=0x105 ==> 0000 0001 0000 0101
简单地将D11置1,变成: 0000 1001 0000 0101 ==> 0x905。实际上可以支持1024*768*16bit色的(0x917),但是这个例程中的显示会不正常。要直接改imode,懒得改了。你自己试吧。
Note 2: 网页版的计算工具无法设置Sync Polarity的+/-,一律用-的。 1100 ==> 0xa
Note 3: 以上数据用网页版计算工具算得。

测试:
HW: Pentium M 1.6G, 512MB RAM, Build-in display
SW:DOS 6.22, Borland C++ 3.1
结果:
在我的测试机上,可以用到1024*768@60Hz, 1024*768@70Hz,
当设到1024*768@75Hz时,显示器报错:超出同步范围。

[编辑 -  11/12/04 by  grant]

[编辑 -  11/12/04 by  grant]
助人乃快乐之本 有人给分就更快乐了 :-)
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-11-12 15:32
将例子程序传上来。
实际上就是VBE中附的例子,我改了初始化图形的部分。
附件名称/大小 下载次数 最后更新
2004-11-12_VESASAMP.CPP (15KB)  6
助人乃快乐之本 有人给分就更快乐了 :-)
grant
驱动老牛
驱动老牛
  • 注册日期2001-05-14
  • 最后登录2007-04-13
  • 粉丝0
  • 关注0
  • 积分350分
  • 威望35点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-11-12 15:36
再发一个计算GTF参数的C源程序。
原来是Linux下的,我改了一下,在DOS下也可以用。
已测试过它算的数据,是可以用的。
附件名称/大小 下载次数 最后更新
2004-11-12_calrefresh.c (22KB)  3
助人乃快乐之本 有人给分就更快乐了 :-)
游客

返回顶部