печать сборок 800 * 600 bmp - PullRequest
       115

печать сборок 800 * 600 bmp

0 голосов
/ 08 марта 2019

Я работаю над сборочным проектом, и мне нужно напечатать изображение 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

1 Ответ

3 голосов
/ 10 марта 2019

Код, который вы сказали, что не писал сам, неверен! Чтобы заполнить весь 256-цветной экран размером 320x200 с помощью растрового изображения того же размера, координата Y должна изменяться от 199 до 0. В настоящее время этот код повторяется от 200 до 1, поэтому нижняя строка растрового изображения никогда не отображается. Это легко исправить.

Когда вы сказали нам, что изменили разрешение экрана на 800x600, вы также должны были сообщить нам разрешение цвета. В приведенном ниже коде я предполагаю, что это 256 цветов, как в примере кода. Кроме того, я представлю решение, которое использует метод LinearFrameBuffer. Оконный подход существует, но он более сложен (конечно, если вы не хотите обрезать слишком много углов). Для видеорежима, который больше не помещается в графическое окно размером 64 КБ (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 очень похож.

Вы получаете значение BytesPerScanLine и адрес LinearFrameBuffer при проверке результатов функции VESA 4F01h ReturnVBEModeInformation.

  • смещение +40 от ModeInfoBlock PhysBasePtr (dword)
  • смещение +50 от ModeInfoBlock LinBytesPerScanLine (слово)

Значение 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...