我一直在做一个装配项目,我需要在屏幕上打印一张bmp图片。我将屏幕的分辨率更改为800 * 600,并且我有一个代码(我没写过)打印320 * 200 bmp图片。我不知道怎么改它打印800 * 600的图片。
有人可以帮忙吗?谢谢。
这是需要更改的代码的一部分:
proc CopyBitmap
; BMP graphics are saved upside-down.
; Read the graphic line by line (200 lines in VGA format),
; displaying the lines from bottom to top.
mov ax, 0A000h
mov es, ax
mov cx,200
PrintBMPLoop:
push cx
; di = cx*320, point to the correct screen line
mov di,cx
shl cx,6
shl di,8
add di,cx
; Read one line
mov ah,3fh
mov cx,320
mov dx,offset ScrLine
int 21h
; Copy one line into video memory
cld ; Clear direction flag, for movsb
mov cx,320
mov si,offset ScrLine
rep movsb ; Copy line to the screen
;rep movsb is same as the following code:
;mov es:di, ds:si
;inc si
;inc di
;dec cx
;... loop until cx=0
pop cx
loop PrintBMPLoop
ret
endp CopyBitmap
你说你自己写的代码是错的!要使用相同大小的位图填充整个320x200 256色屏幕,Y坐标必须在199 downto 0之间变化。此代码当前从200 downto 1循环,因此位图的底线永远不会显示。这很容易解决。
当您告诉我们您已将屏幕分辨率更改为800x600时,您还应告诉我们颜色分辨率。在下面的代码中,我将假设它是256色,就像在示例代码中一样。此外,我将介绍一种使用LinearFrameBuffer方法的解决方案。存在窗口方法但更难(当然如果你不想削减太多的角落)。对于不再适合64KB图形窗口(800 * 600 = 480000字节)的视频模式,它将涉及使用VESA进行存储体切换。
视频窗口位于分段地址0A000h:0000h。这实际上是线性地址000A0000h。
; On entry BX is handle for the file with filepointer at bitmap data!!!
proc CopyBitmap
; BMP graphics are saved upside-down.
; Read the graphic line by line (200 lines in VGA format),
; displaying the lines from bottom to top.
push es
xor ax, ax
mov es, ax
mov cx, 200
PrintBMPLoop:
push cx
; Point to the correct screen line
dec cx ; Y ranging from 199 to 0
movzx edi, cx
imul edi, 320
add edi, 000A0000h
; Read one line
mov dx, offset ScrLine
mov cx, 320
mov ah, 3Fh ; DOS.ReadFile
int 21h
jc WhatIfError?
cmp ax, cx
jne WhatIfError?
; Copy one line into video memory
mov si, dx
add dx, cx ; DX now points to the end of the buffer
CopyLoop:
lodsd ; Load 4 pixels together
stosd [edi] ; This generates an AddressSizePrefix
cmp si, dx
jb CopyLoop
pop cx
loop PrintBMPLoop
pop es
ret
endp CopyBitmap
从检查VESA 4F01h ReturnVBEModeInformation函数的结果中获取BytesPerScanLine值和LinearFrameBuffer地址。
BytesPerScanLine值不必为800.图形环境可能很容易选择1024作为更合理的值。你需要检查而不仅仅是假设。
; On entry BX is handle for the file with filepointer at bitmap data!!!
proc CopyBitmap
; BMP graphics are saved upside-down.
; Read the graphic line by line (600 lines in SVGA format),
; displaying the lines from bottom to top.
push es
xor ax, ax
mov es, ax
mov cx, 600
PrintBMPLoop:
push cx
; Point to the correct screen line
dec cx ; Y ranging from 599 to 0
movzx edi, cx
imul edi, BytesPerScanLine
add edi, LinearFrameBuffer
; Read one line
mov dx, offset ScrLine
mov cx, 800
mov ah, 3Fh ; DOS.ReadFile
int 21h
jc WhatIfError?
cmp ax, cx
jne WhatIfError?
; Copy one line into video memory
mov si, dx
add dx, cx ; DX now points to the end of the buffer
CopyLoop:
lodsd ; Load 4 pixels together
stosd [edi] ; This generates an AddressSizePrefix
cmp si, dx
jb CopyLoop
pop cx
loop PrintBMPLoop
pop es
ret
endp CopyBitmap