打印800 * 600 bmp图片组装

时间:2019-03-08 19:06:13

标签: assembly x86-16 bmp vga

我一直在从事装配项目,因此需要在屏幕上打印bmp图片。我将屏幕的分辨率更改为800 * 600,并且我有一个代码(我没有写过)可以打印320 * 200 bmp图片。我不知道如何更改它以打印800 * 600图片。

有人可以帮忙吗?谢谢。

这是需要更改的代码部分:

ALTER TABLE some_database.some_table
ADD IF NOT EXISTS
PARTITION (pk0 = 'foo', pk1 = 'bar') LOCATION 's3://some-bucket/pk0=foo/pk1=bar/'

1 个答案:

答案 0 :(得分:3)

您说自己没有写的代码是错误的!要用相同大小的位图填充整个320x200 256色屏幕,Y坐标必须从199下降到0。此代码当前从200循环到1,因此永远不会显示位图的底行。这很容易解决。

当您告诉我们将屏幕分辨率更改为800x600时,您还应该告诉我们颜色分辨率。在下面的代码中,我将假定它是256色,就像示例代码中一样。此外,我将提出一个使用LinearFrameBuffer方法的解决方案。存在窗口化的方法,但难度更大(如果您不想开很多角,肯定可以)。对于不再适合64KB图形窗口(800 * 600 = 480000字节)的视频模式,将涉及使用VESA进行组切换。

但是320x200示例也可以使用LFB方法。

视频窗口位于分段地址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

与800x600的代码非常相似。

通过检查VESA 4F01h ReturnVBEModeInformation函数的结果,可以获取BytesPerScanLine值和LinearFrameBuffer地址。

  • ModeInfoBlock PhysBasePtr(双字)的偏移+40
  • 将ModeInfoBlock LinBytesPerScanLine(字)偏移+50

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