问题
I am writing in TASM 3.0 on DosBox 0.74 and I am trying to write in Mode x (Tweaked 13h, unchained mode 13), but how you can see on the image, it's not creating the quite right. It seems that plane 1 (second plane) is not printing at all, and all the others are not in the right order. I know that the code that I will show you is slow and is not productive, but I want to make it work then clean up the code.
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
Here you can see a procedure for printing a bitmap file, worked perfectly on chain-4 mode 13.
- BMPHeight - as name suggest is the height of the picture
- BMPWidth - same
- BMPX - where the picture starts on the screen (x coordinate)
- BMPY - same but Y coordinate
- BMPMaxLine - array of 320 works as a buffer
- VGAPlane - 0/1/2/3 one of the planes
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
This procedure is on every new line of print chooses the plane by the starting x of a line
PlaneByX - MAX_WIDTH / NUMBER_OF_PLANES dup (PLANES), RESET
MAX_WIDTH is 320, NUMBER_OF_PLANES is 4, PLANES is 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
And lastly this code is when selecting a plane
回答1:
Thanks to Fuz for finding an answer and Jonathon Reinhart for making my question clearer. in the VGAPlaneSelect procedure, the al values, which are outputs for the 0x3c5 VGA address, should be 2^(the plane that you want to choose), and for plane 0 2^0 it should be 1, and I wrote 0
so:
cmp [VGAPlane], 0
jne VGAPlaneSelect_0
mov al, 1h
jmp VGAPlaneSelect_end
VGAPlaneSelect_0:
来源:https://stackoverflow.com/questions/59859585/mode-x-in-assembly-x86-16-why-plane-1-is-not-printing-and-all-the-other-planes