我正在 DosBox 0.74 上的 TASM 3.0 中写入,并且我正在尝试写入Mode x https://en.wikipedia.org/wiki/Mode_X(调整了13小时,无束缚模式 13 http://www.brackeen.com/vga/unchain.html),但是你可以在图像中看到,它不太正确。
似乎平面 1(第二个平面)根本没有打印,并且所有其他平面的顺序都不正确。
我知道这里的代码效率低下,但我想让它工作然后清理它。
proc showBMP
push cx
mov ax, 0A000h
mov es, ax
mov cx, [BMPHeight]
mov ax, [BMPWidth]
xor dx, dx
mov si, 4
div si
mov bp, dx
mov dx, [BMPX]
showBMP_nextLine:
call VGAPlaneStartBMP
push cx
push dx
mov di, cx
add di, [BMPY]
mov cx, di
shl cx, 6
shl di, 8
add di, cx
add di, dx
mov ah, 3fh
mov cx, [BMPWidth]
add cx, bp
mov dx, offset BMPMaxLine
int 21h
cld
mov cx, [BMPWidth]
mov si, offset BMPMaxLine
showBMP_nextLine_movsbLoop:
push cx
push di
shr di, 2
mov cl, [ds:si]
mov [es:di], cl
inc [VGAPlane]
inc si
pop di
inc di
pop cx
call VGAPlaneSelect
loop showBMP_nextLine_movsbLoop
pop dx
pop cx
loop showBMP_nextLine
pop cx
ret
endp showBMP
在这里您可以看到打印位图文件的过程,该过程在 chain-4 模式 13 上完美运行。
- BMPHeight - 顾名思义就是图片的高度
- BMP宽度 - 相同
- BMPX - 图片在屏幕上开始的位置(x 坐标)
- BMPY - 相同但 Y 坐标
- BMPMaxLine - 320 的数组用作缓冲区
- VGAPlane - 0/1/2/3 平面之一
proc VGAPlaneStartBMP
push ax
push bx
mov ax, [BMPX]
mov bx, offset PlaneByX
add bx, ax
mov al, [bx]
mov [VGAPlane], al
pop bx
pop ax
call VGAPlaneSelect
ret
endp VGAPlaneStartBMP
此过程对于打印的每一行,通过行的起始 x 选择平面:
PlaneByX - MAX_WIDTH / NUMBER_OF_PLANES 重复 (PLANES),重置
MAX_WIDTH 为 320,NUMBER_OF_PLANES 为 4,PLANES 为 0, 1, 2, 3,
proc VGAPlaneSelect
push ax
push dx
mov al, 02h
mov dx, 03C4h
out dx, al
VGAPlaneSelect_start:
cmp [VGAPlane], 0
jne VGAPlaneSelect_0
mov al, 0h
jmp VGAPlaneSelect_end
VGAPlaneSelect_0:
cmp [VGAPlane], 1
jne VGAPlaneSelect_1
mov al, 1h
jmp VGAPlaneSelect_end
VGAPlaneSelect_1:
cmp [VGAPlane], 2
jne VGAPlaneSelect_2
mov al, 4h
jmp VGAPlaneSelect_end
VGAPlaneSelect_2:
cmp [VGAPlane], 3
jne VGAPlaneSelect_3
mov al, 8h
jmp VGAPlaneSelect_end
VGAPlaneSelect_3:
mov [VGAPlane], 0
jmp VGAPlaneSelect_start
VGAPlaneSelect_end:
inc dx
out dx, al
pop dx
pop ax
ret
endp VGAPlaneSelect
最后这个代码是在选择飞机时。