因为一些特殊的原因
需要在 DOS 环境下作些图形界面的应用
作图形界面当然没有问题
但是一直以来都没有能解决的问题就是:
在DOS中设置了屏幕的高分辨率图形模式后 怎样能调整显示器的刷新率避免画面的细小抖动现在最便宜的17"CRT也能上到85Hz左右 看起来没有闪烁 就是要这个效果以前也提过 没解决 看看现在有办法没有
需要在 DOS 环境下作些图形界面的应用
作图形界面当然没有问题
但是一直以来都没有能解决的问题就是:
在DOS中设置了屏幕的高分辨率图形模式后 怎样能调整显示器的刷新率避免画面的细小抖动现在最便宜的17"CRT也能上到85Hz左右 看起来没有闪烁 就是要这个效果以前也提过 没解决 看看现在有办法没有
我在学习TC时也曾经寻求提高屏幕刷新率,但最后得出这样的结果:屏幕刷新率由操作系统控制。DOS操作系统没有该项功能,TC又不能调用WINDOWS的32位API函数,因此,TC不可能改变屏幕刷新率。建议你不要在这方面浪费太多时间。不过,DOS程序真的需要改变刷新率吗?如果你对屏幕界面感兴趣,你可以转入WINDOWS编程呀,这里有更多的界面等你学。
however 还是要感谢老兄关心 谢谢!
能过设置BX中的D11=1可以使用自定义的CRTC设置
在CRTC结构中可以设置Refresh-Rate
我想这就是我要的但是现在又有个问题:
我在DOS下面用的是WATCOM C++ 11.0
我不知道该怎样把CRTC结构的地址传到 ES:DI 中
用传统的FP_SEG和FP_OFF会失败这应该是个小问题 望大家帮忙!!
比如:struct CRTC info;//...设置info的内容// 设置显示模式的伪代码
ax = 0x4F02
bx = 0x800 + DevMode.ModeNum;这里 es:di 需要指向 &info 该怎么传过去呢
一般来说,只有16位的情况下,我们才考虑段寄存器,因为linux/UNIX 和Windows 32位操作系统都是线形编址的。首先,确定你的info所在的位置,是用DS,ES或是SS来定段的,假定是DS(反正可以通过自己写例子来判断)。可不可以这样写:
push es;
push ds;
pop es;
...其他语句pop es;
这里面要注意,别动乱了BP的值。
8086下ES:DI实际上就是一个far pointer。TC下有个huge指针,千万不能用那样的指针,他会经常调整段地址。如果你的内存寻址被你设置成了32位,问题会比较复杂了。不过如果有人能够这么做,你可以问他,也不用我在这里罗里罗嗦了。
即 A000:0000通过转换 在保护模式中应为 0xA0000但是我并不知道具体的计算方法:(知道计算方法的话 是不是就能把结构的地址转换为实模式中可用的地址呢?
转换后 又怎样能把此地址分解为seg:off这样的方式以传入 es:di呢?(早知今日 当初就该学学ASM)
我不知道该怎样把CRTC结构的地址传到 ES:DI 中
用传统的FP_SEG和FP_OFF会失败
???
我觉得不要使用结构体传值,改为使用 char 数组来传值就行了
unsigned int far part[]=
{0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0xffff,0xffff,0xffff,0xffff,
0x0000,0x4000,0x6000,0x7000,
0x7800,0x7c00,0x7e00,0x7f00,
0x7f80,0x7fc0,0x6c00,0x4600,
0x0600,0x0300,0x0300,0x0180
};
void grpcursor(int x,int y)
{
union REGS ireg;
struct SREGS isreg;
ireg.x.ax=9;
ireg.x.bx=x;
ireg.x.cx=y;
ireg.x.dx=FP_OFF(part);
isreg.es=FP_OFF(part);
}
改用 short int 数组来传值
另:你用 BC3.1 做的这段是实模式还是保护模式?由于要用到 ES:DI
而在 WATCOM C++ 里有 ES DI 的只有 union REGPACK
而使用 RAGPACK 的函数只有 intr( int intno, union REGPACK regs );
而我一调用 intr() 就会出错退出
真是苦恼
也试过 inline asm 还是没搞对
头痛。。
另另:
关于设置刷新率我找到些资料 了解了大概的方法 不过是英文的
如果哪位有兴趣愿意帮忙看看就太好了 不多 就一小段 可惜我看不明白 :([email protected]
不过 BC3.1 的例子是这样的
#include <stdio.h>
#include <string.h>
#include <dir.h>
#include <dos.h>#define CF 1 /* Carry flag */int main(void)
{
char directory[80];
struct REGPACK reg; printf("Enter directory to change to: ");
gets(directory);
reg.r_ax = 0x3B << 8; /* shift 3Bh into AH */
reg.r_dx = FP_OFF(directory);
reg.r_ds = FP_SEG(directory);
intr(0x21, ®);
if (reg.r_flags & CF)
printf("Directory change failed\n");
getcwd(directory, 80);
printf("The current directory is: %s\n", directory);
return 0;
}
gavin1980x(远超):我早就有这个PDF文件了。也许你误解了我的意思我现在的麻烦是:怎样在保护模式里调用实模式实中断的问题。。因为调整refresh rate要用到 int 10h, AX=4F02h...这的确是VBE 3.0up才有的功能但是调用要求在 ES:DI 传入 CRTCInfoBlock 结构地址我不知道该怎样在保护模式中传入此地址或者说不知道怎样在保护模式中Call实模式中断也许要用到 INT 34H 的 DPMI 调用?请指教
我在另一贴中已经作了说明并已结贴此贴主要讨论内容是“怎样调整刷新率”现在调用没有问题了就剩下怎样确定刷新率了我说了关于调整的方法我有资料 下面我把核心部份贴出来
希望大家帮忙弄明白:
AX = 4F02h Set VBE Mode
BX = Desired Mode to setBX:
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 structureOutput: AX = VBE Return StatusNote: All other registers are preserved.////This required function initializes the controller and sets a VBE mode. The format of VESA VBE
mode numbers is described earlier in this document. If the mode cannot be set, the BIOS should
leave the graphics environment unchanged and return a failure error code.
If the requested mode number is not available, then the call will fail, returning AH=01h to indicate
the failure to the application.
If bit D11 is set, the mode will be using the CRTC parameters and pixel clock values passed in the
CRTCInfoBlock structure, rather than using the default values that the BIOS is currently
configured for. This allows the application program or operating system drivers to calculate a new
set of CRTC values (preferably using the VESA Generalized Timing Formula (GTF)
specification) for the mode, and allow the refresh rate to be set to any supported value for the
hardware. If bit D11 is not set, the values passed in ES:DI will be ignored.
If bit D14 is set, the mode will be initialized for use with a flat frame buffer model. The base
address of the frame buffer can be determined from the extended mode information returned by
VBE Function 01h. If D14 is set, and a linear frame buffer model is not available then the call will
fail.
If bit D15 is not set, all reported image pages, based on Function 00h returned information
NumberOfImagePages, will be cleared to 00h in graphics mode, and 20 07 in text mode. Memory
over and above the reported image pages will not be changed. If bit D15 is set, then the contents
of the frame buffer after the mode change is undefined. Note, the 1-byte mode numbers used in
Function 00h of an IBM VGA compatible BIOS use D7 to signify the same thing as D15 does in
this function. If bit D7 is set and the application assumes it is similar to the IBM compatible mode
set using VBE Function 02h, the implementation will fail. VBE aware applications must use the
memory clear bit in D15.
The PixelClock field defines the normalized pixel clock that will be programmed into the
hardware. This value is represented in a 32 bit dword in units of Hz. For example to represent a
pixel clock of 25.18Mhz one would code a value of 25,180,000. Note that this is the normalized
pixel clock that will be programmed, not a physical pixel clock and does not include any scaling
factors for the mode in question. If the hardware needs the pixel clock to be scaled from the
normalized value this will be done by the VBE implementation internally. The normalized pixel
clock is necessary in order to be able to calculate the refresh rate for the specific graphics mode
using the following formula:refreshRate = PixelClock / HorizontalTotal * VerticalTotal // 刷新率计算公式For example a 1024x768 mode with a HTotal of 1360, VTotal of 802, a normalized pixel clock of 75Mhz might be computed as follows:refreshRate Hz = 65 000 000 / 1360 * 802 = 59.59Hz // 这里的三个参数不知道怎样算出来的
The RefreshRate field defines the refresh rate that the CRTC table defines. This value may not
actually be used by the BIOS but must be calculated by the application program using the above
formulas before initializing the mode. This entry may be used by the BIOS to identify any special
cases that may need to be handled when setting the mode for specific refresh rates. The value in
this field should be represented in units if .01 Hz (ie: a value 7200 represents a refresh rate of
72.00Hz).
AthlonxpX86(一滴水):那么要怎样才能确定显示器刷新率的合法上下限呢
或者说要怎样才能计算出特定分辨率下的最大刷新率呢