使用Digital Mars Compiler运行VGA模式代码无画面显示如何解决?
问题原因及修复方案
1. 显存地址定义错误
你当前定义的SCREEN_RAM_START 0xA0000000L是完全错误的地址:
- 16位DOS实模式下,VGA 0x13模式的显存物理地址为
0xA0000,需要用段地址+偏移的方式访问,对应写法为MK_FP(0xA000, 0) - 即使是32位DOS扩展环境下,显存映射地址也只有
0xA0000,你多写了2个0,指针指向了完全无关的内存区域,自然写不到显存
2. 像素偏移计算逻辑错误
set_pixel函数中的偏移计算写错了参数:
- 每行有320个像素,y行的起始偏移应该是
y * SCREEN_WIDTH,你当前写的是y * SCREEN_HEIGHT,就算地址正确,像素也会写到完全错误的位置,很难观测到
3. 编译参数不匹配
Digital Mars的-mmd参数不是生成16位DOS实模式程序的参数,如果你直接在裸DOS/DOSBox环境下运行,会出现BIOS中断调用失效、内存寻址错误的问题:
- 编译16位DOS实模式程序请使用
-ml参数(大内存模型,支持访问1MB以内的地址空间,包含显存区域) - 如果你确实需要用32位扩展开发,需要配套DPMI宿主程序,并且切换VGA模式不能直接调用
int 10h,要通过DPMI提供的中断调用接口操作
修复后可运行的16位实模式代码
#include <dos.h> #include <conio.h> #define VGA256 0x13 #define TEXT_MODE 0x03 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 200 void set_mode(int mode) { _AH = 0; _AL = mode; geninterrupt(0x10); } void set_pixel(int x, int y, unsigned char pixel_color) { unsigned char far *vram = (unsigned char far *)MK_FP(0xA000, 0); vram[(y * SCREEN_WIDTH) + x] = pixel_color; } int main() { set_mode(VGA256); // 用15号亮白色像素,比默认1号蓝色更易观测 set_pixel(100, 150, 15); while (!kbhit()) {} set_mode(TEXT_MODE); return 0; }
内容的提问来源于stack exchange,提问作者Manuel
相关产品推荐
相关产品推荐

