我试图了解如何使用C语言编程实模式MS-DOS。以一些旧的游戏编程书籍为起点。
书中的源代码使用Microsoft C编写,但我正在尝试在OpenWatcom v2下编译它。当我尝试访问指向VGA视频内存起始位置的指针时,遇到了一个问题。
#include <stdio.h>
#include <dos.h>
void Set_Video_Mode(int mode) {
union REGS inregs, outregs;
inregs.h.ah = 0;
inregs.h.al = (unsigned char) mode;
int86(0x10, &inregs, &outregs);
}
int main(void)
{
Set_Video_Mode(0x13);
//the following line throws an error, without it the code compiles and runs
char far *video_buffer = (char far *)0xA0000000L;
while (!kbhit()) { };
Set_Video_Mode(0x03);
return 0;
}
以下是翻译的结果:
是远指针分配引发了以下错误:
VGA.C(33):错误!E1077:缺少 '}'
VGA.C(33):警告!W107:函数'main'缺少返回值
VGA.C(36):错误!E1099:语句必须在函数内。可能原因:缺少 {
这有点令人困惑,看起来像宏定义出错了,或者其他什么问题...
当我使用维基百科上的远指针文章中的代码,并使用同样的编译器时:
#include <stdio.h>
int main() {
char far *p = (char far *)0x55550005;
char far *q = (char far *)0x53332225;
*p = 80;
(*p)++;
printf("%d", *q);
return 0;
}
它已经编译了。
在这两种情况下,编译命令都是wcl -bcl=dos source.c
。
我有点困惑了,似乎无法确定问题所在。 我快要随意添加一些星号和括号,看看是否会起作用...
while
行末的分号是多余的。 - Adrian Moledos.h
。在这种情况下,需要标准的DOS头文件以便进行BIOS功能的视频模式访问。我尝试过将其包含在第二个示例中,但没有任何效果。对于'L'长整型字面量也是如此。 @Adrian Mole - 很好的发现。你看,我已经开始随意添加括号了。唉。 - IronPugfar
指针在Watcom中确实存在,它们被编码为32位值,其中段在上16位,偏移量在下16位。还有一个宏MK_FP
,可以将段和偏移值制作成远指针。0xA0000000将被Watcom DOS编译器解释为0xa000:0x0000,这是EGA/VGA图形区域(64KiB)。模式0x13(OP显然正在使用该模式)将使用该区域作为视频RAM。 - Michael Petch