Eri*_*fat 6 graphics assembly dos vga x86-16
我在 DosBox 0.74 上用 TASM 3.0 编写,我正在尝试在模式 x(调整 13h,未链接模式 13)中编写,但在这里您可以在图像中看到,它不太正确。似乎平面 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
Run Code Online (Sandbox Code Playgroud)
在这里您可以看到打印位图文件的过程,该过程在链 4 模式 13 上完美运行。
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
Run Code Online (Sandbox Code Playgroud)
这个过程,对于每一行打印,通过一行的起始 x 选择平面:
PlaneByX - MAX_WIDTH / NUMBER_OF_PLANES dup (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
Run Code Online (Sandbox Code Playgroud)
最后这个代码是在选择飞机时。
感谢 Fuz 找到答案,感谢 Jonathon Reinhart 让我的问题更加清晰。在VGAPlaneSelect过程中,al值是0x3c5 VGA地址的输出,应该是2^(你想要选择的平面),对于平面0 2^0它应该是1,我写了0
所以:
cmp [VGAPlane], 0
jne VGAPlaneSelect_0
mov al, 1h
jmp VGAPlaneSelect_end
VGAPlaneSelect_0:
Run Code Online (Sandbox Code Playgroud)
执行此VGAPlaneSelect过程的更好方法是:
proc VGAPlaneSelect
push ax
push dx
push cx
mov al, 02h
mov dx, 03C4h
out dx, al
VGAPlaneSelect_start:
mov ax, 1
mov cl, [VGAPlane]
shl ax, cl
cmp [VGAPlane], 4
jne VGAPlaneSelect_end
mov [VGAPlane], 0
jmp VGAPlaneSelect_start
VGAPlaneSelect_end:
mov dx, 03C5h
out dx, al
pop cx
pop dx
pop ax
ret
endp VGAPlaneSelect
Run Code Online (Sandbox Code Playgroud)