Search code examples
assemblydosx86-16tasmdosbox

Assembly program crashes when reading second BMP file


I have a program that prints a from bitmap to screen, the thing is that it successfully prints the first file, but not the second one, even if I swap the BMP files, the first one will always print but not the second one

I found in the debugger that it crushes on int 21h in readHeaderBMP, don't know why though

main:

        mov [BMPX],0
        mov [BMPY],0
        mov [BMPHeight], 200
        mov [BMPWidth], 320
        push offset menu
        call openFile
        push bp
        call createBMP
        pop bp

        mov [BMPX],120
        mov [BMPY],68
        mov [BMPHeight], 25
        mov [BMPWidth], 80
        push offset menuSelect
        call openFile
        push bp
        call createBMP
        pop bp

file managment:

          proc openFile
        push bp
        mov bp, sp
        mov dx, [bp + 4]
        xor ax, ax
        mov ah, 3Dh
        int 21h
        mov [fileHandle], ax
        pop bp
        ret 2
    endp openFile

    proc readHeaderBMP
        xor ax, ax
        mov ah, 3Fh
        mov bx, [fileHandle]
        mov cx, 54
        lea dx, [BMPHeader]
        int 21h
        mov [Error], ax
        ret
    endp readHeaderBMP

    proc readPaletteBMP
        mov ah, 3Fh
        mov cx, 400h
        lea dx, [BMPPalette]
        int 21h
        ret
    endp readPaletteBMP

    proc copyPalleteVRAM
        lea si, [BMPPalette]
        mov cx, 256
        mov dx, 3C8h
        xor al, al
        out dx, al
        inc dx
        copyPalleteVRAM_convert:
            mov al, [si + 2]
            shr al, 2
            out dx, al

            mov al, [si + 1]
            shr al, 2
            out dx, al

            mov al, [si]
            shr al, 2
            out dx, al

            add si, 4
        loop copyPalleteVRAM_convert
        ret
    endp copyPalleteVRAM

    proc showBMP
        push cx
        mov ax, 0A000h
        mov es, ax
        mov cx, [BMPHeight]

        mov ax, [BMPWidth] 
        xor dx, dx
        mov si, 4
        div si
        mov bp, dx

        mov dx, [BMPX]

        showBMP_nextLine:
            push cx
            push dx

            mov di, cx  
            add di, [BMPY] 



            mov cx, di
            shl cx, 6
            shl di, 8
            add di, cx
            add di, dx


            mov ah, 3fh
            mov cx, [BMPWidth]  
            add cx, bp  
            mov dx, offset BMPMaxLine
            int 21h

            mov cx, [BMPWidth]  
            dec cx
            mov si, offset BMPMaxLine
            showBMP_nextLine_movsbLoop:
                push cx
                mov cx, [ds:si]
                mov [es:di], cx
                inc si
                inc di
                pop cx
            loop showBMP_nextLine_movsbLoop

            pop dx
            pop cx

        loop showBMP_nextLine

        pop cx
        ret
    endp showBMP

    proc closeFile
        mov ah, 3Eh
        mov bx, offset FileHandle
        int 21h
        ret
    endp closeFile

    proc createBMP
        call readHeaderBMP
        call readPaletteBMP
        call copyPalleteVRAM
        call showBMP
        call closeFile
        ret
    endp createBMP

and some data:

RESET               equ 0
MAX_WIDTH           equ 320
AMOUNT_OF_COLORS    equ 256
HEADER_SIZE         equ 54
COLOR_SIZE          equ 4

    BMPHeader       db HEADER_SIZE dup (RESET)
    BMPPalette      db AMOUNT_OF_COLORS * COLOR_SIZE dup (RESET)
    BMPX            dw ?
    BMPY            dw ?
    BMPWidth        dw ?
    BMPHeight       dw ?
    BMPMaxLine      db MAX_WIDTH dup (RESET)

    menu            db "menu.bmp", RESET
    menuSelect      db "msl.bmp", RESET

    fileHandle      dw ?

Solution

  • I found the solution, I checked in turbo debugger what was going on, and then I saw that in the file related procedures, in line int 21h in close file, instead of setting cf = 0, ax = 0, the line set cf = 1, ax 06h, which meant an error closing the file, the problem was that I set the bx not as FileHandler, but as an address for FileHandler

        proc closeFile
            mov ah, 3Eh
            mov bx, offset FileHandle ;THIS LINE IS NOT CORRECT
            int 21h                   ;THIS LINE RETURNED AN ERROR
            ret
        endp closeFile
    

    It should be mov bx, [FileHandle]

    Happens to me a lot actually, especially in C, even though I know computer architecture, I always have issues with coding without paying attention to it.