Dar
Dar

Reputation: 21

DosBox stops but no errors in code

I wrote a code in assembly to upload a bmp file. When I run the program, the debugger shows no errors or warnings but the DosBox stops working. Thank you for your help!

IDEAL
MODEL small
STACK 0f500h
DATASEG
filename db 'simonP.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

start:
    mov ax, @data
    mov ds, ax

    ;graphic mode
    mov ax, 13h
    int 10h

    call OpenFile
    call ReadHeader
    call ReadPalette
    call CopyPalette
    call CopyBitMap



proc OpenFile
        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
    mov ah, 3fh
    mov bx, [filehandle]
    mov cx, 54
    mov dx, offset Header
    int 21h 
    ret
ENDP ReadHeader


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


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

    out dx,al

    inc dx

PalLoop:
    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 PalLoop
    ret
ENDP CopyPalette


proc CopyBitMap
    mov ax, 0A000h
    mov es, ax
    mov cx, 200

PrintBMPLoop:
    push cx
    mov di, cx
    shl cx, 6
    shl di, 8
    add di, cx

;read one line
    mov ah, 3fh
    mov cx, 320
    mov si,offset ScrLine
    rep movsb   ;copy line to the screen
                ;rep movsb is the 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



exit:
    mov ax, 4c00h
    int 21h
END start

Upvotes: 1

Views: 511

Answers (1)

Sep Roland
Sep Roland

Reputation: 39166

  1. The OpenFile proc misses mov ah, 3Dh to call the DOS function.
  2. The openError code would better not return to the caller but rather exit to DOS via the Terminate function.
  3. The ReadHeader proc should test for an error.
  4. The ReadPalette proc misses mov bx, [filehandle] and should also test for an error.
  5. The CopyBitMap proc forgets to actually read the data from the file. It merely copies an empty buffer 200 times. Moreover it will never fill the top scanline of the screen due to an one-off-error.
  6. After call CopyBitMap you need to insert jmp exit. Now you are falling through into the OpenFile proc.

I suggest these changes to the CopyBitMap proc

 ...
 cld         ;All to often forgotten!
PrintBMPLoop:
 push cx
 dec cx      ;The famous one-off-error!
 mov di, cx
 shl cx, 6
 shl di, 8
 add di, cx
 ;read one line
 mov ah, 3fh
 mov bx, [filehandle]
 mov cx, 320
 mov dx, offset ScrLine
 int 21h
 jc ...
 mov si, dx
 rep movsb   ;copy line to the screen
 pop cx
 loop PrintBMPLoop
 ...

Upvotes: 2

Related Questions