DOSBox中VGA(640x480x16)调色板部分颜色无法修改求助
首先咱们拆解你遇到的两个核心问题:颜色8-F无法修改是VGA 16色模式的硬件特性导致的,而颜色6的问题大概率是代码里的小疏漏。
一、为什么颜色8-F无法修改?
在VGA的16色图形模式(比如你用的模式12h,640x480x16)中,颜色8-F并不是独立的DAC(数模转换器)条目——它们默认是颜色0-7的高亮度变体。VGA的属性控制器(Attribute Controller)会把颜色8-F映射到DAC的64-71号条目(对应0-7的高亮版本),你直接修改DAC的8-F号条目自然不会生效。
要让颜色8-F成为独立的可自定义颜色,你需要修改属性控制器的调色板模式寄存器(索引10h),关闭“高亮映射”功能:
修改属性控制器的步骤
属性控制器的端口是3C0h,这个端口是索引和数据复用的,操作前需要先读取3DAh的状态寄存器解锁它:
; 解锁属性控制器 in al, 3DAh ; 设置调色板模式寄存器索引(10h) mov al, 10h out 3C0h, al ; 读取当前值(属性控制器读写的强制时序要求) in al, 3C0h ; 清零位3(高亮使能位),关闭高亮映射 and al, 0F7h ; 写回修改后的值 out 3C0h, al
执行这段代码后,颜色8-F就会直接使用DAC的8-F号条目,你之前的调色板设置代码就能正常修改它们了。
二、为什么颜色6无法修改?
看你的代码,有一个容易忽略的细节:设置视频模式的指令写法不严谨,虽然结果正确,但可能导致后续逻辑的隐性问题。另外你可以检查下setpalete宏的参数:你用的030h(十六进制)是合法的(VGA DAC分量是6位,范围0-63),但如果想要更明显的颜色效果,可以调整为03Fh(最大值)测试。
设置视频模式的代码建议改成更清晰的标准写法:
mov ah, 00h mov al, 12h int 10h
这段代码明确指定了AH=0(设置视频模式功能)、AL=12h(640x480x16模式),避免因寄存器值的歧义导致问题。
三、修正后的完整代码示例
下面是整合了上述修复的完整代码,包含属性控制器修改、调色板设置和颜色填充:
setpalete MACRO index,r,g,b mov dx, 3c8h mov al, index out dx, al mov dx, 3c9h mov al, r out dx, al ; 设置R分量(0-63) mov al, g out dx, al ; 设置G分量 mov al, b out dx, al ; 设置B分量 ENDM Start: ; 设置视频模式为640x480x16(模式12h) mov ah, 00h mov al, 12h int 10h ; 修改属性控制器,关闭颜色8-F的高亮映射 in al, 3DAh ; 解锁属性控制器 mov al, 10h ; 选择调色板模式寄存器(索引10h) out 3C0h, al in al, 3C0h ; 读取当前寄存器值 and al, 0F7h ; 清零位3,关闭高亮映射 out 3C0h, al ; 写回修改后的值 ; 设置颜色6为深灰色 setpalete 06h, 030h, 030h, 030h ; 设置颜色8为纯红色 setpalete 08h, 03Fh, 000h, 000h ; 设置颜色F为亮蓝色 setpalete 0Fh, 000h, 000h, 03Fh ; 填充屏幕为颜色6 mov ax, 0A000h mov es, ax mov dx, 03C4h ; 位平面索引寄存器 mov ax, 0206h ; 索引2(Map Mask),值06h(对应颜色6的位平面) out dx, ax mov al, 0FFh mov di, 0 mov cx, 38400 ; 640*480/8 = 38400字节 rep stosb ; 暂停等待按键 mov ah, 00h int 16h ; 恢复文本模式 mov ah, 00h mov al, 03h int 10h ; 退出程序 mov ah, 4Ch int 21h END Start
四、DOSBox相关注意事项
DOSBox 0.74-3的默认配置对VGA模拟是比较准确的,但如果你之前修改过dosbox.conf中的vga相关选项,可能会影响调色板的行为,建议恢复默认配置测试。
内容的提问来源于stack exchange,提问作者Saar BS

