中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net 论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

中国DOS联盟论坛
现在时间是 2026-06-14 02:40
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 哪位大虾知道101号显示模式???着急
楼 主 哪位大虾知道101号显示模式???着急 发表于 2006-04-26 20:50 ·  中国 陕西 西安 电信
初级用户
积分 96
发帖 32
注册 2006-04-15 16:03
UID 53877
状态 离线
101号显示模式起始地址是0x0000000吗???
是不是线形影射。。。。。。???
我做了一下直接写屏,显示有点乱阿?
我算了一下640*480*256色好像要300k,是不是超出地址范围了??
着急中。。。。。。
2 VESA的101号模式-648*480*256色 发表于 2006-04-27 10:21 ·  中国 广东 深圳 宝安区 电信
高级用户
★★
积分 668
发帖 295
注册 2005-07-26 00:00
UID 41110
性别 男
来自 广东深圳
状态 离线
/*
由于显存有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);
}
3 发表于 2006-04-27 14:02 ·  中国 陕西 西安 电信
初级用户
积分 96
发帖 32
注册 2006-04-15 16:03
UID 53877
状态 离线
楼上的否给个tc版的,模式我切换过去了。。。。
640*256*480,64k够了吗???
4 TC版本的VESA_640*480*256色 发表于 2006-04-27 16:29 ·  中国 广东 深圳 宝安区 电信
高级用户
★★
积分 668
发帖 295
注册 2005-07-26 00:00
UID 41110
性别 男
来自 广东深圳
状态 离线
/*
由于显存有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);
}
5 发表于 2006-04-27 20:52 ·  中国 陕西 西安 电信
初级用户
积分 96
发帖 32
注册 2006-04-15 16:03
UID 53877
状态 离线
谢谢这位大哥。。。
我把你的程序看懂了。。。
自己的程序可以运行了,不过好像效率很低啊,,是不是换页次数太多了???
6 简单有效地解决VESA的写点效率 发表于 2006-04-28 09:45 ·  中国 广东 深圳 电信
高级用户
★★
积分 668
发帖 295
注册 2005-07-26 00:00
UID 41110
性别 男
来自 广东深圳
状态 离线
/*
真正的换页函数可以如下所示
函数名称: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);
}
7 简单有效地解决VESA的写点效率(接上) 发表于 2006-04-28 10:03 ·  中国 广东 深圳 电信
高级用户
★★
积分 668
发帖 295
注册 2005-07-26 00:00
UID 41110
性别 男
来自 广东深圳
状态 离线
(1)如果每写一个点,就换页,那么显示速度是相当慢的,难以忍受。
(2)为了进一步提高效率,有时直接将换页函数改造后嵌入到代码中。
(3)为了提高效率,尽量用C语言与汇编语言交叉编程,既易读懂又能提高效率!
(4)可以参考WinSail V2.0嵌入式系统
8 发表于 2006-04-28 21:22 ·  中国 陕西 西安 电信
初级用户
积分 96
发帖 32
注册 2006-04-15 16:03
UID 53877
状态 离线
今天早上优化了一下,大概能刷到25次每秒,要是每次换页那就速度慢的无语了。。。
而且我还不进行比较了,反正65536个点后换一次页,全屏就这样处理的。
不过感觉还是很闪。。。
怎么能减少闪阿???
winsail在哪〉???????
9 发表于 2006-06-29 10:29 ·  中国 北京 鹏博士BGP
中级用户
★★
CPU
积分 362
发帖 96
注册 2004-07-08 00:00
UID 28010
性别 男
来自 北京
状态 离线
路过,收下了。^_^
10 发表于 2006-06-29 14:33 ·  中国 湖南 长沙 电信
中级用户
★★
积分 282
发帖 126
注册 2006-05-17 22:29
UID 55724
状态 离线
CPU访问显存很慢的!
就算是EMS、XMS不断在基本内存、扩展内存切换数据都比CPU访问显存快很多!

应该先在内存(可考虑XMS)里画好,然后等到垂直回扫时将数据传输到显存。

如果功底足够的话,建议进保护模式,直接访问物理内存。这样又比XMS交换快得多。




推荐《图形程序开发人员指南(Michael Abrash's Graphics Programming Black Book)》:
http://www.netyi.net/Resource/933a25cf-fa0e-4dab-b9d7-e58a0ea8f52e.aspx
人类存在的目的就是试图理解人类为何存在
论坛跳转: