|
lofe811
初级用户
积分 96
发帖 32
注册 2006-4-15
状态 离线
|
『楼 主』:
哪位大虾知道101号显示模式???着急
101号显示模式起始地址是0x0000000吗???
是不是线形影射。。。。。。???
我做了一下直接写屏,显示有点乱阿?
我算了一下640*480*256色好像要300k,是不是超出地址范围了??
着急中。。。。。。
|
|
2006-4-26 20:50 |
|
|
firstsail
高级用户
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第
2 楼』:
VESA的101号模式-648*480*256色
/*
由于显存有1~32M内存(甚至更多),它是通过页框映射到页框中,
一般情况下,首地址在A000:0000中,页框为64K字节。
*/
/*
请在Win98或纯DOS下运行!在Win2000或WinXP下有可能执行不成功!
*/
/*在WinSail V2.0中大体是这样来切换到VESA的640*480*256模式*/
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
typedef int BOOL;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
//显示模式上640*480*265色
BOOL SetVESA_640_480_256()
{
int nResult = 0;
int nMode = 0x101;
asm mov ax, 04F02H
asm mov bx, nMode
asm int 10h
asm mov nResult,ax
return((nResult == 0x4F)?TRUE:FALSE);
}
//换页函数,64K为一个显示页,页框在内存A000:0000处
void ChangeFrame(int nPage)
{
asm push cx
asm mov ax,04F05H
asm mov bx,0
asm mov dx,nPage
asm int 10h
asm pop cx
return;
}
void FillScreen(int nColor)
{
//总的页数,//256色下,一个点对应一个字节
unsigned uPages = (unsigned)((640L * 480L) / (1L<<16));
unsigned uOffset= (unsigned)((640L * 480L) % (1L<<16));
unsigned char far * pFrame = (unsigned char far *)MK_FP(0xA000, 0000);
for (unsigned i = 0; i < uPages; i++)
{
//切换到第i页
::ChangeFrame(i);
//将A000:0000 ~ A000:FFFF的64K字节都填充为nColor的颜色
_fmemset(pFrame + 0u * 0x8000u, nColor, 0x8000u);
_fmemset(pFrame + 1u * 0x8000u, nColor, 0x8000u);
}
if (uOffset != 0u)
{
//切换到最后一页
::ChangeFrame(uPages);
_fmemset(pFrame, nColor, uOffset);
}
}
int main()
{
//上640*480*256色
::SetVESA_640_480_256();
::FillScreen(WHITE);
getch();
//恢复到文本模式
asm mov ax, 3
asm int 10h
return(0);
return(0);
}
|
|
2006-4-27 10:21 |
|
|
lofe811
初级用户
积分 96
发帖 32
注册 2006-4-15
状态 离线
|
『第
3 楼』:
楼上的否给个tc版的,模式我切换过去了。。。。
640*256*480,64k够了吗???
|
|
2006-4-27 14:02 |
|
|
firstsail
高级用户
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第
4 楼』:
TC版本的VESA_640*480*256色
/*
由于显存有1~64M内存(甚至更多),它是通过页框映射到显存(1~64M)中,
一般情况下,首地址在A000:0000中,页框大小为64K字节。
注意:记住任何时候显存只占用系统内存的A000:0000 ~ A000:FFFF或者
B000:0000 ~ B000:FFFF,通过换页来映射到显存中。
页框大小一般为64K字节,也有的显卡是128K字节的页,但很少见。
*/
/*
请在Win98或纯DOS下运行!在Win2000或WinXP下有可能执行不成功!
*/
#include <conio.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned int WORD;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/*显示模式上640*480*265色*/
BOOL SetVESA_640_480_256()
{
int nResult, nMode;
nResult = 0;
nMode = 0x101;
asm mov ax, 04F02H
asm mov bx, nMode
asm int 10h
asm mov nResult,ax
return((nResult == 0x4F)?TRUE:FALSE);
}
/*换页函数,64K为一个显示页,页框在内存A000:0000处*/
void ChangeFrame(int nPage)
{
asm push cx
asm mov ax,04F05H
asm mov bx,0
asm mov dx,nPage
asm int 10h
asm pop cx
return;
}
/*填充整个屏幕*/
void FillScreen(int nColor)
{
/*计算总页数和不足页的字节数,256色下,一个点对应一个字节*/
WORD i;
WORD uPages, uOffset;
BYTE far * pFrame;
uPages = (unsigned)((640L * 480L) / (1L<<16));
uOffset= (unsigned)((640L * 480L) % (1L<<16));
pFrame = (BYTE far *)MK_FP(0xA000, 0000);
for (i = 0; i < uPages; i++)
{
/*切换到第 i 页*/
ChangeFrame(i);
/*将A000:0000 ~ A000:FFFF的64K字节都填充为nColor的颜色*/
_fmemset(pFrame + 0u * 0x8000u, nColor, 0x8000u);
_fmemset(pFrame + 1u * 0x8000u, nColor, 0x8000u);
}
if (uOffset != 0u)
{
/*切换到最后一页*/
ChangeFrame(uPages);
_fmemset(pFrame, nColor, uOffset);
}
}
int main()
{
/*上640*480*256色*/
SetVESA_640_480_256();
/*填充整个屏幕为绿色*/
FillScreen(GREEN);
getch();
/*填充整个屏幕为蓝色*/
FillScreen(BLUE);
getch();
/*填充整个屏幕为红色*/
FillScreen(RED);
getch();
/*填充整个屏幕为淡蓝色*/
FillScreen(LIGHTBLUE);
getch();
/*恢复到文本模式*/
asm mov ax, 3
asm int 10h
return(0);
}
|
|
2006-4-27 16:29 |
|
|
lofe811
初级用户
积分 96
发帖 32
注册 2006-4-15
状态 离线
|
『第
5 楼』:
谢谢这位大哥。。。
我把你的程序看懂了。。。
自己的程序可以运行了,不过好像效率很低啊,,是不是换页次数太多了???
|
|
2006-4-27 20:52 |
|
|
firstsail
高级用户
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第
6 楼』:
简单有效地解决VESA的写点效率
/*
真正的换页函数可以如下所示
函数名称:KernelChangePage
入口参数:int nPage --- 将换的页面
int nOldPage -- 上一次最后一个点所在的页面
出口参数:无
返回值:当前页
*/
int KernelChangePage(int nPage, int nOldPage)
{
/*如果将换的页面与当前页相同,则跳转*/
asm mov ax, nPage
asm cmp ax, nOldPage
asm jz label_exit
asm push cx
/*调用VESA中断来换页*/
asm mov ax,04F05H
asm mov bx,0
asm mov dx,nPage
asm int 10h
asm pop cx
label_exit:;
return(nPage);
}
|
|
2006-4-28 09:45 |
|
|
firstsail
高级用户
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第
7 楼』:
简单有效地解决VESA的写点效率(接上)
(1)如果每写一个点,就换页,那么显示速度是相当慢的,难以忍受。
(2)为了进一步提高效率,有时直接将换页函数改造后嵌入到代码中。
(3)为了提高效率,尽量用C语言与汇编语言交叉编程,既易读懂又能提高效率!
(4)可以参考WinSail V2.0嵌入式系统
|
|
2006-4-28 10:03 |
|
|
lofe811
初级用户
积分 96
发帖 32
注册 2006-4-15
状态 离线
|
『第
8 楼』:
今天早上优化了一下,大概能刷到25次每秒,要是每次换页那就速度慢的无语了。。。
而且我还不进行比较了,反正65536个点后换一次页,全屏就这样处理的。
不过感觉还是很闪。。。
怎么能减少闪阿???
winsail在哪〉???????
|
|
2006-4-28 21:22 |
|
|
Gandalf
中级用户
CPU
积分 362
发帖 96
注册 2004-7-8 来自 北京
状态 离线
|
|
2006-6-29 10:29 |
|
|
zyl910
中级用户
积分 282
发帖 126
注册 2006-5-17
状态 离线
|
『第
10 楼』:
CPU访问显存很慢的!
就算是EMS、XMS不断在基本内存、扩展内存切换数据都比CPU访问显存快很多!
应该先在内存(可考虑XMS)里画好,然后等到垂直回扫时将数据传输到显存。
如果功底足够的话,建议进保护模式,直接访问物理内存。这样又比XMS交换快得多。
推荐《图形程序开发人员指南(Michael Abrash's Graphics Programming Black Book)》:
http://www.netyi.net/Resource/93 ... 7-e58a0ea8f52e.aspx
|
人类存在的目的就是试图理解人类为何存在 |
|
2006-6-29 14:33 |
|