8 bit BMP Loader

Anyone have tutorial/source for loading BMP (320x200x256) in assembler? All i have found was C source.

Thanks...

Comments

  • Try this code:
    [code]
    ; Bitmap Display Program (bitmap.asm)

    ; The ShowBMP procedure loads a Windows type BMP file
    ; and display it on the screen. Input parameters:
    ; DS:DX points to an ASCIIZ string containing the
    ; BMP file path. The maximum resolution is 320x200, with
    ; 256 colors. (by Diego Escala, Miami, Florida)

    .model small
    .stack 100h
    .186

    .code

    extrn Open_InFile:proc, Close_File:proc

    ; PUBLIC ShowBMP

    main proc
    ; load data segment register
    mov ax, @data
    mov ds, ax


    mov dx, offset graph_file
    ; save graphics mode

    mov ah, 0fh ; preserve original video mode
    int 10h
    push ax


    call ShowBMP

    call waitkey
    ; restore graphics mode

    pop ax ; restore original mode
    mov ah, 00h
    int 10h


    ; Exit program
    mov ax,4C00h
    int 21h
    main endp

    waitkey proc
    push ax
    mov ah, 10h ; wait for keyboard input
    int 16h
    pop ax
    ret
    waitkey endp


    ShowBMP proc
    pusha ; Save registers
    call Open_InFile ; Open file pointed to by DS:DX
    jc FileErr ; Error? Display error message and quit
    mov bx,ax ; Put the file handle in BX
    call ReadHeader ; Reads the 54-byte header containing file info
    jc InvalidBMP ; Not a valid BMP file? Show error and quit
    call ReadPal ; Read the BMP's palette and put it in a buffer
    push es
    call InitVid ; Set up the display for 320x200 VGA graphics
    call SendPal ; Send the palette to the video registers
    call LoadBMP ; Load the graphic and display it
    call Close_File ; Close the file
    pop es

    jmp ProcDone

    FileErr:
    mov ah,9
    mov dx,offset msgFileErr
    int 21h
    jmp ProcDone

    InvalidBMP:
    mov ah,9
    mov dx,offset msgInvBMP
    int 21h

    ProcDone:
    popa ; Restore registers
    ret
    ShowBMP endp

    ; Check the first two bytes of the file. If they do not
    ; match the standard beginning of a BMP header ("BM"),
    ; the carry flag is set.

    CheckValid proc
    clc
    mov si,offset Header
    mov di,offset BMPStart
    mov cx,2 ; BMP ID is 2 bytes long.
    CVloop:
    mov al,[si] ; Get a byte from the header.
    mov dl,[di]
    cmp al,dl ; Is it what it should be?
    jne NotValid ; If not, set the carry flag.
    inc si
    inc di
    loop CVloop

    jmp CVdone

    NotValid:
    stc

    CVdone:
    ret
    CheckValid endp

    GetBMPInfo proc
    ; This procedure pulls some important BMP info from the header
    ; and puts it in the appropriate variables.

    mov ax,header[0Ah] ; AX = Offset of the beginning of the graphic.
    sub ax,54 ; Subtract the length of the header
    shr ax,2 ; and divide by 4
    mov PalSize,ax ; to get the number of colors in the BMP
    ; (Each palette entry is 4 bytes long).
    mov ax,header[12h] ; AX = Horizontal resolution (width) of BMP.
    mov BMPWidth,ax ; Store it.
    mov ax,header[16h] ; AX = Vertical resolution (height) of BMP.
    mov BMPHeight,ax ; Store it.
    ret
    GetBMPInfo endp

    InitVid proc
    ; This procedure initializes the video mode and makes ES point to
    ; video memory.

    mov ax,13h
    int 10h ; Set video mode to 320x200x256.
    push 0A000h
    pop es ; ES = A000h (video segment).
    ret
    InitVid endp

    LoadBMP proc
    ; BMP graphics are saved upside-down. This procedure reads the graphic
    ; line by line, displaying the lines from bottom to top. The line at
    ; which it starts depends on the vertical resolution, so the top-left
    ; corner of the graphic will always be at the top-left corner of the screen.

    ; The video memory is a two-dimensional array of memory bytes which
    ; can be addressed and modified individually. Each byte represents
    ; a pixel on the screen, and each byte contains the color of the
    ; pixel at that location.

    mov cx,BMPHeight ; We're going to display that many lines
    ShowLoop:
    push cx
    mov di,cx ; Make a copy of CX
    shl cx,6 ; Multiply CX by 64
    shl di,8 ; Multiply DI by 256
    add di,cx ; DI = CX * 320, and points to the first
    ; pixel on the desired screen line.

    mov ah,3fh
    mov cx,BMPWidth
    mov dx,offset ScrLine
    int 21h ; Read one line into the buffer.

    cld ; Clear direction flag, for movsb.
    mov cx,BMPWidth
    mov si,offset ScrLine
    rep movsb ; Copy line in buffer to screen.

    pop cx
    loop ShowLoop
    ret
    LoadBMP endp

    ; This procedure checks to make sure the file is a valid BMP,
    ; and gets some information about the graphic.

    ReadHeader proc
    mov ah,3fh
    mov cx,54
    mov dx,offset Header
    int 21h ; Read file header into buffer.

    call CheckValid ; Is it a valid BMP file?
    jc RHdone ; No? Quit.
    call GetBMPInfo ; Otherwise, process the header.

    RHdone:
    ret
    ReadHeader endp

    ; Read the video palette.

    ReadPal proc
    mov ah,3fh
    mov cx,PalSize ; CX = Number of colors in palette.
    shl cx,2 ; CX = Multiply by 4 to get size (in bytes)
    ; of palette.
    mov dx,offset palBuff
    int 21h ; Put the palette into the buffer.
    ret
    ReadPal endp

    SendPal proc
    ; This procedure goes through the palette buffer, sending information about
    ; the palette to the video registers. One byte is sent out
    ; port 3C8h, containing the number of the first color in the palette that
    ; will be sent (0=the first color). Then, RGB information about the colors
    ; (any number of colors) is sent out port 3C9h.

    mov si,offset palBuff ; Point to buffer containing palette.
    mov cx,PalSize ; CX = Number of colors to send.
    mov dx,3c8h
    mov al,0 ; We will start at 0.
    out dx,al
    inc dx ; DX = 3C9h.
    sndLoop:
    ; 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 only allows
    ; values of up to 63. Dividing by 4
    ; gives a good value.
    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 sndLoop
    ret
    SendPal endp

    .data
    Header label word
    HeadBuff db 54 dup('H')
    palBuff db 1024 dup('P')
    ScrLine db 320 dup(0)

    BMPStart db 'BM'

    PalSize dw ?
    BMPHeight dw ?
    BMPWidth dw ?

    msgInvBMP db "Not a valid BMP file.",7,0Dh,0Ah,24h
    msgFileErr db "Error opening file.",7,0Dh,0Ah,24h

    graph_file db "name.bmp",0


    end main[/code]
    \\||////
    @)
    ASHLEY4.

    Batteries not included, Some assembly required.
  • : Try this code:
    : [code]
    : ; Bitmap Display Program (bitmap.asm)
    :
    : ; The ShowBMP procedure loads a Windows type BMP file
    : ; and display it on the screen. Input parameters:
    : ; DS:DX points to an ASCIIZ string containing the
    : ; BMP file path. The maximum resolution is 320x200, with
    : ; 256 colors. (by Diego Escala, Miami, Florida)
    :
    : .model small
    : .stack 100h
    : .186
    :
    : .code
    :
    : extrn Open_InFile:proc, Close_File:proc
    :
    : ; PUBLIC ShowBMP
    :
    : main proc
    : ; load data segment register
    : mov ax, @data
    : mov ds, ax
    :
    :
    : mov dx, offset graph_file
    : ; save graphics mode
    :
    : mov ah, 0fh ; preserve original video mode
    : int 10h
    : push ax
    :
    :
    : call ShowBMP
    :
    : call waitkey
    : ; restore graphics mode
    :
    : pop ax ; restore original mode
    : mov ah, 00h
    : int 10h
    :
    :
    : ; Exit program
    : mov ax,4C00h
    : int 21h
    : main endp
    :
    : waitkey proc
    : push ax
    : mov ah, 10h ; wait for keyboard input
    : int 16h
    : pop ax
    : ret
    : waitkey endp
    :
    :
    : ShowBMP proc
    : pusha ; Save registers
    : call Open_InFile ; Open file pointed to by DS:DX
    : jc FileErr ; Error? Display error message and quit
    : mov bx,ax ; Put the file handle in BX
    : call ReadHeader ; Reads the 54-byte header containing file info
    : jc InvalidBMP ; Not a valid BMP file? Show error and quit
    : call ReadPal ; Read the BMP's palette and put it in a buffer
    : push es
    : call InitVid ; Set up the display for 320x200 VGA graphics
    : call SendPal ; Send the palette to the video registers
    : call LoadBMP ; Load the graphic and display it
    : call Close_File ; Close the file
    : pop es
    :
    : jmp ProcDone
    :
    : FileErr:
    : mov ah,9
    : mov dx,offset msgFileErr
    : int 21h
    : jmp ProcDone
    :
    : InvalidBMP:
    : mov ah,9
    : mov dx,offset msgInvBMP
    : int 21h
    :
    : ProcDone:
    : popa ; Restore registers
    : ret
    : ShowBMP endp
    :
    : ; Check the first two bytes of the file. If they do not
    : ; match the standard beginning of a BMP header ("BM"),
    : ; the carry flag is set.
    :
    : CheckValid proc
    : clc
    : mov si,offset Header
    : mov di,offset BMPStart
    : mov cx,2 ; BMP ID is 2 bytes long.
    : CVloop:
    : mov al,[si] ; Get a byte from the header.
    : mov dl,[di]
    : cmp al,dl ; Is it what it should be?
    : jne NotValid ; If not, set the carry flag.
    : inc si
    : inc di
    : loop CVloop
    :
    : jmp CVdone
    :
    : NotValid:
    : stc
    :
    : CVdone:
    : ret
    : CheckValid endp
    :
    : GetBMPInfo proc
    : ; This procedure pulls some important BMP info from the header
    : ; and puts it in the appropriate variables.
    :
    : mov ax,header[0Ah] ; AX = Offset of the beginning of the graphic.
    : sub ax,54 ; Subtract the length of the header
    : shr ax,2 ; and divide by 4
    : mov PalSize,ax ; to get the number of colors in the BMP
    : ; (Each palette entry is 4 bytes long).
    : mov ax,header[12h] ; AX = Horizontal resolution (width) of BMP.
    : mov BMPWidth,ax ; Store it.
    : mov ax,header[16h] ; AX = Vertical resolution (height) of BMP.
    : mov BMPHeight,ax ; Store it.
    : ret
    : GetBMPInfo endp
    :
    : InitVid proc
    : ; This procedure initializes the video mode and makes ES point to
    : ; video memory.
    :
    : mov ax,13h
    : int 10h ; Set video mode to 320x200x256.
    : push 0A000h
    : pop es ; ES = A000h (video segment).
    : ret
    : InitVid endp
    :
    : LoadBMP proc
    : ; BMP graphics are saved upside-down. This procedure reads the graphic
    : ; line by line, displaying the lines from bottom to top. The line at
    : ; which it starts depends on the vertical resolution, so the top-left
    : ; corner of the graphic will always be at the top-left corner of the screen.
    :
    : ; The video memory is a two-dimensional array of memory bytes which
    : ; can be addressed and modified individually. Each byte represents
    : ; a pixel on the screen, and each byte contains the color of the
    : ; pixel at that location.
    :
    : mov cx,BMPHeight ; We're going to display that many lines
    : ShowLoop:
    : push cx
    : mov di,cx ; Make a copy of CX
    : shl cx,6 ; Multiply CX by 64
    : shl di,8 ; Multiply DI by 256
    : add di,cx ; DI = CX * 320, and points to the first
    : ; pixel on the desired screen line.
    :
    : mov ah,3fh
    : mov cx,BMPWidth
    : mov dx,offset ScrLine
    : int 21h ; Read one line into the buffer.
    :
    : cld ; Clear direction flag, for movsb.
    : mov cx,BMPWidth
    : mov si,offset ScrLine
    : rep movsb ; Copy line in buffer to screen.
    :
    : pop cx
    : loop ShowLoop
    : ret
    : LoadBMP endp
    :
    : ; This procedure checks to make sure the file is a valid BMP,
    : ; and gets some information about the graphic.
    :
    : ReadHeader proc
    : mov ah,3fh
    : mov cx,54
    : mov dx,offset Header
    : int 21h ; Read file header into buffer.
    :
    : call CheckValid ; Is it a valid BMP file?
    : jc RHdone ; No? Quit.
    : call GetBMPInfo ; Otherwise, process the header.
    :
    : RHdone:
    : ret
    : ReadHeader endp
    :
    : ; Read the video palette.
    :
    : ReadPal proc
    : mov ah,3fh
    : mov cx,PalSize ; CX = Number of colors in palette.
    : shl cx,2 ; CX = Multiply by 4 to get size (in bytes)
    : ; of palette.
    : mov dx,offset palBuff
    : int 21h ; Put the palette into the buffer.
    : ret
    : ReadPal endp
    :
    : SendPal proc
    : ; This procedure goes through the palette buffer, sending information about
    : ; the palette to the video registers. One byte is sent out
    : ; port 3C8h, containing the number of the first color in the palette that
    : ; will be sent (0=the first color). Then, RGB information about the colors
    : ; (any number of colors) is sent out port 3C9h.
    :
    : mov si,offset palBuff ; Point to buffer containing palette.
    : mov cx,PalSize ; CX = Number of colors to send.
    : mov dx,3c8h
    : mov al,0 ; We will start at 0.
    : out dx,al
    : inc dx ; DX = 3C9h.
    : sndLoop:
    : ; 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 only allows
    : ; values of up to 63. Dividing by 4
    : ; gives a good value.
    : 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 sndLoop
    : ret
    : SendPal endp
    :
    : .data
    : Header label word
    : HeadBuff db 54 dup('H')
    : palBuff db 1024 dup('P')
    : ScrLine db 320 dup(0)
    :
    : BMPStart db 'BM'
    :
    : PalSize dw ?
    : BMPHeight dw ?
    : BMPWidth dw ?
    :
    : msgInvBMP db "Not a valid BMP file.",7,0Dh,0Ah,24h
    : msgFileErr db "Error opening file.",7,0Dh,0Ah,24h
    :
    : graph_file db "name.bmp",0
    :
    :
    : end main[/code]
    : \\||////
    @)
    : ASHLEY4.
    :
    : Batteries not included, Some assembly required.
    :

    Thanks!
    i have extracted much usefull info from this program, but i'm realising that BMP is a very akward and annoying layout of the data, so i have decided to modify my little asm program to, instead of displaying
    the pic, extract just the palette and raw pic data and save these as a sequential file which another program will load as 'raw'
    data and display onscreen (for a game)
  • Here are some ideas first 24bit bmp are much easier than 8bit bmp, i am making a pmode OS and this is the code to display a 640x480 24bit bmp.
    [code]
    ;'''''''''''''''''''''''''''''''''''''''''''''''''''';
    ; PutBmp24 ; puts a 24bit bmp to screen ;
    ;----------------------------------------------------;
    ; ;
    ; Input: ;
    ; ;
    ; ;
    ; Output: ;
    ; ;
    ;....................................................;

    PutBmp24:
    mov ax,linear_sel
    mov es,ax
    xor edi,edi
    mov edi,[ModeInfo_PhysBasePtr]
    mov esi,0x200000
    add esi,640*3*479
    add esi,ebx
    newln24:
    push esi
    push edi
    mov ecx,480
    cld
    cli
    rep movsd
    sti
    pop edi
    pop esi
    sub esi,640*3
    add edi,640*3
    cmp esi,0x200000
    jge newln24

    ret [/code]
    Also i have made a dos game in asm, which has a small display pcx function you can get the game with asm code here : http://www.falconrybells.co.uk/
    called "pong.zip" a pong game in space.
    My OS, which is a full 32bit pmode Dos/Xbox like OS, with pmode int , floppy, cd, vesa, etc, would be great for games etc, it is going to be the new v2os.
    May be you could drop by the v2os site, if you are interested in making some games in a xbox like os.
    ( a test ver will be available in the next weeks or so,)

    http://www.v2os.cx/

    \\||////
    @)
    ASHLEY4.

    Batteries not included, Some assembly required.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories