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 here you can see in the image, it's not 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 here is inefficient, but I want to make it work and then clean it up.
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, which 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, for each line of printing, 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.
VGAPlaneSelect
logic withmov al, 1; mov cl, [VgAPlane]; shl al, cl
– Pharmacognosy0, 1, 4, 8
for1, 2, 4, 8
. It is likely that theshl
-based code I wrote doesn't work as-is; it was more intended to be an inspiration for an implementation of your own design. – Pharmacognosy