Search code examples
assemblyx86-16tasmdosbox

How do I print a .bmp image multiple times?


I'm working on an assembly project for class and I have some code. My problem is that I have errors because the code is not designed to print the same .bmp image multiple times.
What I need is some code that I can use so I can print my .bmp image multiple times. Any advice will be very helpful. Thanks!

I've tried some other code for printing .bmp files in assembly but wasn't successful.
If you have some sort of code for printing .bmp files, it will be very useful.

CODE:

IDEAL
MODEL small
STACK 100h
DATASEG
;================================
filename db 'test.bmp',0

filehandle dw ?

Header db 54 dup (0)

Palette db 256*4 dup (0)

ScrLine db 320 dup (0)

ErrorMsg db 'Error', 13, 10,'$'
;================================
CODESEG
;================================
proc OpenFile

    ; Open file

    mov ah, 3Dh
    xor al, al
    mov dx, offset filename
    int 21h

    jc openerror
    mov [filehandle], ax
    ret

    openerror:
    mov dx, offset ErrorMsg
    mov ah, 9h
    int 21h
    ret
endp OpenFile
proc ReadHeader

    ; Read BMP file header, 54 bytes

    mov ah,3fh
    mov bx, [filehandle]
    mov cx,54
    mov dx,offset Header
    int 21h
    ret
    endp ReadHeader
    proc ReadPalette

    ; Read BMP file color palette, 256 colors * 4 bytes (400h)

    mov ah,3fh
    mov cx,400h
    mov dx,offset Palette
    int 21h
    ret
endp ReadPalette
proc CopyPal

    ; Copy the colors palette to the video memory
    ; The number of the first color should be sent to port 3C8h
    ; The palette is sent to port 3C9h

    mov si,offset Palette
    mov cx,256
    mov dx,3C8h
    mov al,0

    ; Copy starting color to port 3C8h

    out dx,al

    ; Copy palette itself to port 3C9h

    inc dx
    PalLoop:

    ; Note: Colors in a BMP file are saved as BGR values rather than RGB.

    mov al,[si+2] ; Get red value.
    shr al,2 ; Max. is 255, but video palette maximal

    ; value is 63. Therefore dividing by 4.

    out dx,al ; Send it.
    mov al,[si+1] ; Get green value.
    shr al,2
    out dx,al ; Send it.
    mov al,[si] ; Get blue value.
    shr al,2
    out dx,al ; Send it.
    add si,4 ; Point to next color.

    ; (There is a null chr. after every color.)

    loop PalLoop
    ret
endp CopyPal

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
;================================
start:
mov ax, @data
mov ds, ax
;================================

    ; Graphic mode
    mov ax, 13h
    int 10h

    ; Process BMP file
    call OpenFile
    call ReadHeader
    call ReadPalette
    call CopyPal
    call CopyBitmap

    ; Wait for key press
    mov ah,1

    int 21h
    ; Back to text mode
    mov ah, 0
    mov al, 2
    int 10h
;================================
exit:
    mov ax, 4c00h
    int 21h
    END start

It's my first time using this website, so I'm not sure how things work here, but I can upload my project if needed.


Solution

  • Repeating is simply a matter of closing the file and then looping back in the program. To close the file you use DOS function 3Eh

    proc CloseFile
      mov  ah, 3Eh
      mov  bx, [filehandle]
      int  21h
      ret
    endp CloseFile
    

      mov  ax, 0013h       ;Graphic mode
      int  10h
    Again:
      call OpenFile
      call ReadHeader
      call ReadPalette
      call CopyPal
      call CopyBitmap
      call CloseFile
      mov  ah, 01h         ;Key
      int  21h
      cmp  al, 27
      jne  Again           ;Loop until users presses <ESC>
      mov ax, 0003h        ;Text mode
      int 10h
    exit:
      mov ax, 4C00h
      int 21h