i made a simple exemple of scrolling bmp and i didnt understand Two things:
1.why the image start from the middle
2.why after the x change on the screen there is a line in the middle
i really need help besause i on it a week and i cant solve it
the code:
IDEAL
MODEL large
Macro ReadBmp FileName
mov [Lines],0
mov [Weight],0
mov ax,[Y]
mov [CurrentY],ax
mov [XScreen],0
mov [YScreen],0
mov dx, offset FileName ;Mov Dx Offset Of File To Read It
;call ClearBuff
call ReadToBuffer ;Call Proc That Move Values To Buffer
call ShowBMP
mov ax,[CurrentY]
mov [Y],ax
EndM
P386
STACK 256
RightDown equ 77
LeftDown equ 75
UpDown equ 72
DownDown equ 80
ScreenRam equ 0A000h
DATASEG
ErrorMsg DB 'There Is A Problem To Show The File$'
Handle DW ?
File DB 'Map.bmp',0
Index DD ?
X DW 0
Y DW 0
CurrentY DW 0
XScreen DW 0
YScreen DW 0
Weight DW 0
Lines DB 0
;SizeFile DD 0
SEGMENT BufferBmp para public ;'DATA'
DB 65535 DUP(0)
ENDS
CODESEG
Start:
mov ax, @data
mov ds, ax
mov ax, BufferBmp
mov es, ax
mov ax, 0013h
int 10h
Draw:
ReadBmp File
lop:
mov ah,00
int 16h
cmp ah,RightDown
je Right
cmp ah,LeftDown
je Left
cmp ah,UpDown
je Up
cmp ah,DownDown
je Down
cmp ah,1
je Exit
jmp lop
Right:
add [X],5
jmp Draw
Left:
sub [X],5
jmp Draw
Up:
sub [Y],5
jmp Draw
Down:
add [Y],5
jmp Draw
Exit:
mov ax,04c00h
int 21h
Proc ClearBuff near
mov si,0
mov al,15
NoFinish:
mov [es:si],al
inc si
cmp si,65535
jne NoFinish
;-----------------------------Clear Screen-----------------------------;
mov ax,ScreenRam
xor di,di
mov cx,320*200/2
mov al,0d
mov ah,0d
rep stosw
;-----------------------------Clear Screen-----------------------------;
ret
endp
Proc ReadToBuffer near
;--------------------OpenFile Use Handle--------------------;
mov ah, 3Dh ;INT 21 Know If Ah == 3dh He Need To Open/Create File
mov al, 0 ;Read Only
;mov dx,offset FileName
int 21h
jc @@Err
mov [Handle], ax ;Handle On ax Go To Var
;--------------------Copy Lines To Buffer------------------;
;--------------------Move Pointer To Check End Of File--------------------;
; mov ah, 42h ;int 21h Know That If AH == 42h He Move Pointer On File
; mov al, 02 ;End Of File To Know Size Of A File
; mov bx, [Handle] ;BX = file handle
; xor ecx,ecx ;CX:DX = offset from origin of new file position.
; xor edx,edx ;CX:DX = offset from origin of new file position.
; int 21h
; jc @@Err
; ;Enter The Image Size Into A Variable
; mov [SizeFile],eax
; mov eax,65536
; mul edx
; add [SizeFile],eax
; cmp [SizeFile],0
; je @@Err
;--------------------Move Pointer To Check End Of File--------------------;
@@Lop:
;--------------------Calculate index By WY+X-------------;
mov eax, 1920 ;Eax == 1920(Weight Of Map)
xor ebx, ebx ;ebx = 0
mov bx, [Y] ;Bx == Y
mul ebx ;W*Y
xor ebx, ebx ;Ebx = 0
add ax, [X] ;WY+X
;--------------------Calculate index By WY+X-------------;
;--------------------Flip Image--------------------;
;mov [index],eax ;index == eax
;mov eax,[SizeFile] ;eax == All Byte Image
;sub eax,[index] ;Eax - Index
;--------------------Flip Image--------------------;
mov [index],eax ;index == eax
xor edx, edx ;edx = 0
mov ebx, 65536 ;ebx = 65536
div ebx ;Dx = Remains,ax = dose
mov ecx, eax ;CX = high order word of number of bytes to move
xor ebx, ebx ;edx = 0
;CX:DX distance to move file pointer: offset is (CX * 65536) + DX
;--------------------Move Pointer To Read Data--------------------;
mov ah, 42h ;int 21h Know That If AH == 42h He Move Pointer On File
mov al, 00 ;Current Location Plus Offset
mov bx, [Handle] ;BX = file handle
;CX:DX = offset from origin of new file position.
int 21h
jc @@Err
;--------------------Move Pointer To Read Data--------------------;
;--------------------Read Data--------------------;
mov bx, [Handle] ;BX = file handle
mov dx, [Weight] ;DS:DX = pointer to read buffer
pusha
push ds
mov ax, BufferBmp
mov ds, ax
mov cx, 320 ;CX = number of bytes to read---;320 = Line;
mov ah, 3Fh
int 21H
pop ds
popa
jc @@Err
;--------------------Read Data--------------------;
inc [Lines]
inc [Y] ;Add Y To Calculate Position
add [Weight], 320 ;Add Weight X
cmp [Lines], 200 ;Check End
jne @@Lop
mov ah, 3Eh ;Close File
mov bx,[Handle] ;BX = file handle
int 21H
jc @@Err
ret
@@Err:
mov ax, 3 ; Set text mode
int 10h
mov dx, offset ErrorMsg
mov ah, 09h
int 21h ;Print Error
jmp Exit
endp
Proc ShowBMP near
mov si,0 ;Start From The Begining Of Buffer
mov bx,0 ;page 0
@@Horizontal:
mov ah,0Ch ;int 10h Know That If AH == 0Ch He Write Graphics Pixel at Coordinate
mov al, [es:si] ;Color
mov cx,[XScreen] ;X
mov dx,[YScreen] ;Y
int 10h
inc si ;mov to next pixel
inc [XScreen] ;Add X
cmp [XScreen],320 ;Check End Line
jne @@Horizontal
inc [YScreen] ;Add Y
mov [XScreen],0 ;Start New Line
cmp [YScreen],200 ;Check End Of Image
jne @@Horizontal
ret
endp
End Start
The program using this image: https://drive.google.com/file/d/1T8aBZr8mtCUmQL2WKmQfklmEMfaOCklG/view?usp=sharing
add ax, [X]
When calculating the file offset you forget to consider the carry from adding X
mov eax, 1920 ;Eax == 1920(Weight Of Map)
xor ebx, ebx ;ebx = 0
mov bx, [Y] ;Bx == Y
mul ebx ;W*Y
xor ebx, ebx ;Ebx = 0
mov bx, [X]
add eax, ebx <<<< correct addition
The conversion of this 32-bit number into CX:DX is simply:
push eax
pop dx
pop cx
That division by 65536 was not useful.
Now you can call DOS.function 42h.
Every .BMP graphics file starts with a header that contains important information about the picture. For your 256-color bitmap file these are:
Then come the pixel data that you need. That's why your calculation of the file offset should add eax, 14+40+1024.
movzx eax, word [Y] ; Y position within bitmap
imul eax, 1920 ; Width of bitmap
movzx ebx, word [X] ; X position within bitmap
lea eax, [eax+ebx+1078] <<<< Plus offset to start of pixel data
push eax
pop dx
pop cx