一开始我也使用了 16 色图形模式。但是对于 16 色图形模式,我们需要至少有一个端口访问才能将一个像素设置到屏幕上。而且这个端口访问速度很慢。所有其他具有 8、15、16、24、32 位颜色的常规图形模式都更容易使用(就像 van Uitkon 在评论中所说)。
这是我第一个使用 16 色的小程序之一。在下面的像素设置例程中,我展示了如何使用 16 色图形模式将单个像素设置到屏幕上。
.MODEL SMALL
.386
.CODE
ORG 0100h
MOV AX, @DATA
MOV DS, AX
MOV ES, AX
MOV AX, 0A000h
MOV FS, AX
MOV AX, 12h ; Mode 640 x 480 x 4 bit color
INT 10h
P10B: MOV AX, 140h ; X Position
MOV BX, 0F0h ; Y Position
P111: MOV CX, 1 ; Radius
MOV [XPOS], AX ; Edit: need right square bracket, was "}" before
MOV [YPOS], BX ; Edit: need right square bracket, was "}" before
MOV [RADI], CX
MOV [R0E], AX
ADD AX, CX
P200: MOV GS, AX
MOV AX, [R0E]
SUB AX, [XPOS]
ADD AX, [YPOS]
MOV [R10], AX
SUB AX, [YPOS]
MOV [R14], AX
MOV AX, [R0E]
SUB AX, [XPOS]
XOR SI, SI
MOV DI, 2
CALL P600
MOV AX, [R14]
MOV SI, 2
XOR DI, DI
CALL P600
MOV AX, GS
INC WORD PTR [R0E]
CMP [R0E], AX
JNZ P200
INC BYTE PTR CS:[P111+1] ; increase Radius
CMP BYTE PTR CS:[P111+1], 0E0h
JNZ P10B
MOV BYTE PTR CS:[P111+1], 1
TASTE: MOV AX, 1
INT 16h
CMP AL, 20h ; space key
JNZ TASTE
MOV AX, 3 ; Text-Mode
INT 10h
MOV AX, 4C00h
INT 21h
;--------------------- S u b - Routinen ------------------------------
P600: MUL AX
MOV [SI+R18], AX
MOV AX, [RADI]
MUL AX
MOV [R16], AX
SUB AX, [SI+R18]
MOV CX, AX
MOV DX, 1
MOV BX, 1
P406: STC
SBB CX, DX
JB P411
INC BX
ADD DX, 2
JMP P406
P411: ADD BX, [DI+XPOS]
MOV [DI+R06], BX
SUB BX, [DI+XPOS]
MOV AX, [DI+XPOS]
SUB AX, BX
MOV [DI+R0A], AX
MOV AX, [SI+R0E]
MOV [SI+R06], AX
SUB AX, [SI+XPOS]
MOV BX, [SI+XPOS]
SUB BX, AX
MOV [SI+R0A], BX
MOV BP, [R06]
MOV BX, [R08]
CALL PIXEL
MOV BP, [R06] ; Edit: undifined symbol R069
MOV BX, [R0C]
CALL PIXEL
MOV BP, [R0A]
MOV BX, [R08]
CALL PIXEL
MOV BP, [R0A]
MOV BX, [R0C]
PIXEL: MOV CX, BP ; BP = X / BX = Y
SHR CX, 3
MOV AX, 50h ; Lenght of scanline
MUL BX
ADD AX, CX
MOV SI, AX
INC CX
MOV AX, CX
SHL AX, 3
SUB AX, BP
DEC AX
MOV CL, AL
MOV AH, 1 ; 2 ^ (((X/8) + 1) * 8 - X) - 1
SHL AH, CL ; = Pixel pos.
MOV DX, 3CEh
MOV AL, 8 ; Pixel-Mask
OUT DX, AX
MOV AX, 205h ; Write Mode 2
OUT DX, AX
MOV AH, 5 ; color
MOV AL, FS:[SI] ; dummy read for to adjust the address
MOV FS:[SI], AH
RET
.DATA
XPOS DW ?
YPOS DW ?
RADI DW ?
R06 DW ?
R08 DW ?
R0A DW ?
R0C DW ?
R0E DW ?
R10 DW ?
R14 DW ?
R16 DW ?
R18 DW ?
.STACK 20h
END
抱歉,我现在编辑错误行。