我很难理解如何在CGA/EGA/VGA视频图形模式中使用颜色。我特别关注的视频模式是0Dh(EGA 320x200)和12h(VGA 640x480)。这两种模式都有4个平面,因此有16种颜色。
我的(可能不正确的)理解是,我应该通过向端口03C4h写入位掩码来激活一组平面,然后当我写入视频内存时,数据只会被写入已激活的平面。我主要使用了这个文档来获取信息,尽管我也遇到了其他几个教程和讨论: http://www.techhelpmanual.com/89-video_memory_layouts.html 现在我正在尝试在视频内存的第一个单词(屏幕左上角)中以所有可能的颜色编写像素。我将1加载为初始位掩码到AH中,并将1位加载到BX中。然后,在循环中,我增加AH并移位(
任何想法为什么它不按我预期的工作?
我的(可能不正确的)理解是,我应该通过向端口03C4h写入位掩码来激活一组平面,然后当我写入视频内存时,数据只会被写入已激活的平面。我主要使用了这个文档来获取信息,尽管我也遇到了其他几个教程和讨论: http://www.techhelpmanual.com/89-video_memory_layouts.html 现在我正在尝试在视频内存的第一个单词(屏幕左上角)中以所有可能的颜色编写像素。我将1加载为初始位掩码到AH中,并将1位加载到BX中。然后,在循环中,我增加AH并移位(
SHL
)BX中的位以下一次击中不同的像素。我通过离开已存在的像素不变来将BX OR
到 A000h:0000h
中添加每个像素。
我期望看到的是屏幕左上角所有可能的16种EGA颜色构成的一行像素。然而我实际看到的是7个白点和1个亮黄色点,并且它们之间有黑色像素。我做错了什么?
此外,每个教程都说在使用平面之前必须向端口03CEh
写入0005h
。这样做的目的是什么?当我将这些代码注释掉后,我仍然可以在其他程序中使用平面(我的意思是)在以前的编程中,当我在视频内存中写入不同单词时(所以我不需要一个由视频内存中的单个字表示的16像素块中的不同颜色像素);并且当我使用BIOS函数(例如INT 10h / AH = 0Ch)书写像素时也成功使用了平面图形,但我仍想理解如何在没有BIOS的情况下使用平面图形,因为我认为BIOS功能很慢。
以下是我的代码(缩进针对8个字符宽度的制表符进行了优化,因此在这里看起来有点奇怪):
; ----------------------------------------------------------------------
; PLANE - TEST PLANAR VIDEO MODE
; nasm -o plane.com plane.asm
; ----------------------------------------------------------------------
ORG 100h ; Code starts at CS:0100h
MOV AX, 0F00h ; Get current video mode
INT 10h
PUSH AX ; Save it to restore later
MOV AX, 000Dh ; Set video mode 0Dh (EGA 320x200, 16 color)
INT 10h
MOV DX, 03CEh ; Set up for plane masking
MOV AX, 0005h
OUT DX, AX
MOV AX, 0A000h ; Load video segment to ES
MOV ES, AX ; and set Destination Index
XOR DI, DI ; to write data to A000h:0000h
MOV CX, 14 ; Iterate through all plane masks
MOV AX, 0100h ; First plane mask is 01h
MOV BX, 1 ; Initial pixel to write
LOOP_PIXEL:
CALL SET_PLANES ; Set planes according to AH
PUSH BX ; Save current pixels to [DATA+CX*2]
MOV BX, CX ; for debugging purposes
SHL BX, 1
MOV DX, ES:[DI]
MOV [DATA + BX], DX
POP BX
OR ES:[DI], BX ; Add new pixel to video memory from BX
SHL BX, 1 ; Shift BX so we'll activate a different pixel next time
INC AH ; Increment plane mask
LOOP LOOP_PIXEL
XOR AX, AX ; Wait for keypress
INT 16h
POP AX ; Restore previous video mode
XOR AH, AH
INT 10h
INT 20h ; Exit program
; ----------------------------------------------------------------------
; SET_PLANES: Set video color plane mask.
;
; Inputs:
; AH - plane mask
;
; Outputs:
; None.
; ----------------------------------------------------------------------
SET_PLANES:
PUSH AX
PUSH DX
MOV DX, 03C4h
MOV AL, 02h
OUT DX, AX
POP DX
POP AX
RET
DATA:
任何想法为什么它不按我预期的工作?