Skocz do zawartości
docxxx

[asembler] Wyswietlanie Bmp

Rekomendowane odpowiedzi

Mam taki oto program to wyswietlania pliku bmp (320*200 i 256 kolorow). Wada programu jest to, ze wyswietla obraz do gory nogami (poza tym jest ok). Co trzeba zrobic, zeby wyswietlil to normalnie?

(jak chcecie to skopiujcie, skompilujcie i spawdzcie)

 

.model tiny

.stack 100h

.386

 

.data

plik db "fota.bmp",0

blad db "Blad otwarcia. Pliku nie znaleziono$"

paleta db 768 dup (0) ;wyzerowana tablica 768=3*256 (RGB)

bufor db 4 dup (0) ;R,G,B,x

UchwytPliku dw ?

 

 

.code

 

start:

mov ax,@data

mov ds,ax

mov es,ax ;dodatkowy segment danych

mov dx,offset plik

 

mov al,00h ;parametr otwarcia pliku tylko do odczytu

mov ah,3dh ;otwarcie pliku; w ax uchwyt pliku

 

int 21h

jc blad_otwarcia ;gdy plik nie zostanie znalezniony-CF jest ustawiony i AX zawiera kod bledu

 

mov bx,ax ;do bx nalezy przeniesc uchwyt pliku

mov uchwytpliku,bx ;przeniesienie uchwytu pliku do zmiennej \"UchwytPliku\"

 

mov dx,offset paleta

mov cx,54 ;pomijamy naglowek skladajacy sie z 54 bajow (dane informacyjne pliku)

mov ah,3fh ;odczyt z pliku 54 bajtow naglowka

int 21h

 

mov cx,256

mov di,offset paleta ;do 16-bitowego rejestru indeksowego, wskaznika dla danych, wrzucamy palete

 

WczytujPalete:

push cx ;wrzuc na stos

mov cx,4 ;wczytaj kombinacje B,G,R,x (odwrotnie i x jako zarezerwowane)

mov dx,offset bufor

mov ah,3fh

int 21h

 

;R ; pt- mozliwy wpis do al-8bitowego rejestru 4bitowego bufora

mov al,byte ptr[bufor+2] ;wrzuc po kolei do bufora RGB, RGB, RGB...

shr al,1

shr al,1

stosb ;zapisz od razu 4 punkty ekranu

;G

mov al, byte ptr[bufor+1]

shr al,1

shr al,1

stosb

 

;B

mov al,byte ptr[bufor]

shr al,1

shr al,1

stosb

 

pop cx ;teraz zdejmij ze stosu

loop WczytujPalete

 

mov ax,13h ;ustaw 320*200

int 10h

 

mov dx,offset paleta ;ustaw palete kolorow

mov cx,256

mov bx,0 ;kolor- czarny

mov al,12h ;ustaw rejestr kolorow

mov ah,10h

int 10h

 

;odczyt

push ds ;wczytaj obrazek do bufora

mov bx,UchwytPliku

mov ax,seg ekran

mov ds,ax

mov dx,0

mov cx, 320*200

mov ah,3fh

int 21h

pop ds

 

push ds ;znowu wrzucamy segment danych na stos, zeby nie ulegly nadpisaniu

push es

mov ax,seg ekran ;skopiuj z bufora na ekran

mov ds,ax

mov ax,0a000h ;adres segmentu w pamieci operacyjnej, od jakiego rozpoczyna sie pamiec ekranu

mov es,ax

mov si,0 ;rejestr indeksowy, wskaznik do danych w segmencie danych

mov di,0 ;rejestr indeksowy wskaznik do danych

mov cx,19200 ;ilosc pikseli do wyswietlenia 320*240/4

cld ;wyzerowanie znacznika kierunku D (zwiekszenie rejestrow indeksowych SI i DI)

rep movsd ;przekopiuj do es:[(E)DI] wartosci DS:[(E)SI] oraz zmniejszenie (E)DI i (E)SI o rozmiar komorki

pop es

pop ds

 

mov ah,08h ;czekaj na klawisz

int 21h

 

mov ax,3h ;tryb tekstowy

int 10h

jmp koniec

 

blad_otwarcia:

mov ah,09h

mov dx,offset blad

int 21h

 

koniec:

mov ah,4ch

int 21h

 

 

ekran segment use16

db 0ffffh dup (15) ;65536

ekran ends

 

end start

 

 

Cos trzeba zrobic chyba z :

 

push es

mov ax,seg ekran ;skopiuj z bufora na ekran

mov ds,ax

mov ax,0a000h

mov es,ax

mov si,0 ;rejestr indeksowy, wskaznik do danych w segmencie danych

mov di,0 ;rejestr indeksowy wskaznik do danych

mov cx,19200 ;ilosc pikseli do wyswietlenia 320*240/4

cld

rep movsd

 

Ale ja juz sie zamotalem

 

Z gory dzieki za odpowiedz.

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Po pierwsze, skoro w DOSie na przerwaniu 13h mozesz wyswietlic max 320x200x8bpp to nie wiem skad tam sie nagle bierze 320x240 :)

 

Skoro wyswietla sie obraz 'do gory nogami' to znaczy sie ze rep movsd tego nie rozwiaze, bo potrzebujesz kopiowac obrazek linia po linii, kolejno wczytac pierwsza i zapisac jako ostatnia, wczytac druga zapisac jako przedostania itd itd

 

Nie odpalalem programu i ten fragment sklecilem w 30s wiec jak nad nim posiedzisz to wymyslisz bardziej optymalne rozwiazanie, chodzilo mi o zobrazowanie, mianowicie:

 

mov si, 320*200;rejestr indeksowy, wskaznik do danych w segmencie danychmov di,0;rejestr indeksowy wskaznik do danychsub si, 320 ; cofnij na ostatnia liniemov dl, 200; 200 linii do skopiowaniacopy_scanline:mov cx, 320/4rep movsdsub si, 640 ; cofnij na poczatek swojej( bo movsd zmienil wartosc ) i na poczatek poprzedniej liniidec dljne copy_scanline

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...

×   Wklejono zawartość z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Odnośnik został automatycznie osadzony.   Przywróć wyświetlanie jako odnośnik

×   Przywrócono poprzednią zawartość.   Wyczyść edytor

×   Nie możesz bezpośrednio wkleić grafiki. Dodaj lub załącz grafiki z adresu URL.

Ładowanie


×
×
  • Dodaj nową pozycję...