[ASM] Mandelbrot, blad, pomocy

0

moze mi ktos powiedziec co jest tutaj nie tak ???? program po odpaleniu rysuje mi w ulamek sekundy wszystko na jeden kolor, a powinien z 1-1,5 sek liczyc i narysowac mi zbior mandelbrota. Dalem to juz kumplowi i tez nie widzi bledu, a ja wymiekam - 2 dni nad tym siedze i nic :/.

TITLE fraktale

.MODEL small	;model pamieci
.486		;rodz. procesora
;----------------------------------------------------------------------------

.STACK 512	;deklaracja stosu

;----------------------------------------------------------------------------

.DATA		;segment danych


XMIN  DQ -2.2	;poczatkowa wsp x fraktala
YMIN  DQ -1.2	;poczatkowa wsp y fraktala
XMAX  DQ  0.9	;koncowa wsp x fraktala
YMAX  DQ  1.2	;koncowa wsp y fraktala
SZER  DQ 320	;szer. ekranu
WYS   DQ 200	;wys.  ekranu
iter DW 10	                ;liczba iteracji
prom DQ 8.0	;promien Z

    ;Z = a+ib	;wynik iteracji
zRe DQ 0.0
zIm DQ 0.0

    ;C = a+ib	;parametr
cRe DQ 0.0
cIm DQ 0.0

    ;T = a+ib	;tymczasowe
tRe DQ 0.0
tIm DQ 0.0

porown	DW 0	;wynik porownania w koprocesorze
i   DD ?	                ;wspolrzedna x (licznik petli)
j   DD ?	                ;wspolrzedna y (licznik petli)
poz DW ?	                ;pozycja na ekranie (320*i+j)
kolor DB 2
;----------------------------------------------------------------------------

.CODE		;segment kodu

Start:		;PROGRAM GLOWNY

    mov ax, @data		;ustaw DS
    mov ds, ax

    ;uruchom tryb graficzny
    mov ax, 13h
    int 10h


    ;rysuj piksel (tak dla pomocy :p)
    ;mov ax, 0a000h		;adres pamieci obrazu
    ;mov es, ax 		;do es
    ;mov di, 32160		;pozycja (srodek)
    ;mov byte ptr es:[di], 10	;kolor

;TO CO MA SIE WYKONAC :-)

    xor eax, eax
    mov i, eax		;i=0
    mov j, eax		;j=0
    mov poz, ax		;poz=0


    finit			;start koprocesora

petla_j:			;dla wps. y
    xor eax, eax
    mov i, eax
 petla_i:			;dla wsp x

    fldz			;st(0) = 0.0
    fldz			;st(1) = 0.0
    fstp zRe			;zRe = 0.0
    fstp zIm			;zIm = 0.0, stos pusty

    ;obliczamy cRe
    ;wzor: i/SZER*(XMAX-XMIN)+XMIN
    fild i			;st(0)=i
    fild SZER		;st(1)=i, st(0)=SZER
    fdiv st(1),st		;st(0)= i/SZER
    fld XMIN		;st(0)=XMIN, st(1)=i/SZER
    fld XMAX		;st(0)=XMAX, st(1)=XMIN, st(2)=i/SZER
    fsubp st(1), st		;st(0)=XMAX-XMIN, st(1)=i/SZER
    fmulp st(1), st		;st(0)=i/SZER*(XMAX-XMIN)
    fld XMIN		;st(0)=XMIN, st(1)=i/SZER*(XMAX-XMIN)
    faddp st(1),st		;st(0)=WYNIK
    fstp cRe			;cRe=WYNIK, stos pusty

    ;obliczamy cIm tak jak powyzej
    ;wzor: j/WYS*(YMAX-YMIN)+YMIN
    fild j
    fild WYS
    fdivp st(1), st
    fld YMIN
    fld YMAX
    fsubp st(1), st
    fmulp st(1), st
    fld YMIN
    faddp st(1), st
    fstp cIm

    mov cx, iter		;ustaw licznik petli

   petla_iter:
    ;sprawdz czy nie wychodzimy poza obszar
    fld zRe			;st(0)=zRe
    fld zRe			;st(0)=zRe, st(1)=zRe
    fmulp st(1), st		;st(0)=zRe^2
    fstp tRe			;tRe=zRe^2, stos pusty
    fld zIm			;st(0)=zIm
    fld zIm			;st(0)=zIm
    fmulp st(1), st		;st(0)=zIm^2
    fstp tIm			;tIm=zIm^2, stos pusty

    fld tRe			;st(0)=tRe
    fld tIm			;st(0)=tRe, st(1)=tIm
    faddp st(1), st		;zRe^2+zIm^2
    fcomp prom		;porownaj z promieniem
    fstsw ax			;przenies wynik porownania do ax (ah)
    sahf			;zapisz ah do rejestru flag
    jae rysuj		;rysuj plik gdy zRe^2+zIm^2 >=PROMIEN

    ;obliczamy nowe zIm (zIm=2*zRe*zIm+cIm)
    fld zRe			;st(0)=zRe
    fld zRe			;st(0)=zRe, st(1)=zRe
    faddp st(1), st		;st(0)=2*zRe
    fld zIm			;st(0)=zIm, st(1)=2*zRe
    fmulp st(1), st		;st(0)=2*zRe*zIm
    fld cIm			;st(0)=zIm, st(1)=2*zRe*zIm
    faddp st(1), st		;st(0)=wynik
    fstp zIm			;zIm=2*zRe*zIm+cIm

    ;obliczamy nowe zRe (zRe=zRe^2 - zIm^2 + cRe)
    fld tRe			;st(0)=zRe^2
    fld tIm			;st(0)=zIm^2, st(1)=zRe^2
    fsubp st(1), st		;st(0)=zRe^2-zIm^2
    fld cRe			;st(0)=cRe, st(1)=zRe^2-zIm^2
    faddp st(1), st		;st(0)=wynik
    fstp zRe			;zapisz do zRe, stos pusty
    loop petla_iter		;kolejna iteracja

   rysuj:
    mov ax, 0a000h		;adres pamieci obrazu
    mov es, ax		;do es
    mov di, poz		;pozycja (srodek)
    mov ax, cx		;sprawdz ile bylo iteracji
    cmp ax, iter	
    je dalej
    mov al, 10		;kolor 1
   dalej:
    mov al, 2		;kolor 2
    mov byte ptr es:[di], al	;rysuj punkt o ustalonym kolorze
    inc(poz)                                 ;ustaw sie na nastepnym pikselu
    inc(i)                                     ;zwieksz i (polozenie na osi x)
    mov eax, i                             ;sprawdz czy koniec linii
    cmp eax, 320
    jnz petla_i                              ;nie, to jeszcze raz

    inc(j)                                     ;byl koniec linii - ustaw sie w nastepnej
    mov eax, j
    cmp eax, 200                         ;sprawdz czy koniec ekranu
    jnz petla_j                              ;nie to jeszcze raz

koniec:
;KONIEC PROGRAMU GLOWNEGO
    ;czekaj na klawisz
    xor ah, ah
    int 16h

    ;zakoncz tryb graficzny
    mov ax, 3h
    int 10h

    ;czekaj na klawisz
    ;xor ah, ah
    ;int 16h

    ;KONIEC
    mov ax, 4c00h
    int 21h

END Start   ;KONIEC
;----------------------------------------------------------------------------

dla prownania tak to napisalem w c (z roznica, ze korzysta z wiekszej ilosci kolorow)

#include <stdio.h>
#include <graphics.h>
#include <math.h>

#define WIDTH   640.0
#define HEIGHT  480.0
#define PROMIEN 100.0
#define XMIN  	-2.2
#define XMAX 	0.9
#define YMIN 	-1.2
#define YMAX	1.2


struct Complex
{
	float Re;
	float Im;
};


int main()
{
int drv=9, mode=2;
int x, y, k;
Complex z, c, tmp;


	initgraph(&drv, &mode, "");

	for (y=0; y<getmaxy(); y++)
	{
		for (x=0; x<getmaxx(); x++)
		{
			c.Re = x/WIDTH*(XMAX-XMIN) + XMIN;
			c.Im = y/HEIGHT*(YMAX-YMIN) + YMIN;

			z.Re = 0;
			z.Im = 0;

			for (k=0; k<128; k++)
			{
				tmp.Re = z.Re*z.Re;
				tmp.Im = z.Im*z.Im;

				if ( tmp.Re+tmp.Im >= PROMIEN )
					break;

				z.Im = 2 * z.Re * z.Im + c.Im;
				z.Re = tmp.Re - tmp.Im + c.Re;
			}
			putpixel(x, y, k%16);
		}
	}

	getchar();
	closegraph();

	return 0;
}

z gory dzieki
pozdrawiam

0

Nie wiem czy komuś się będzie aż tak nudzić żeby to sprawdzać =]

0

no mi sie tak "nudzi", ze mnie juz glowa boli :/
a poza tym znalazlem poki co takie bledy, ale niestety po poprawieniu niewiele sie zmienilo :(:

w miejscu gdzie jest obliczane cRe:
zaladowac nalezy na odwrot XMIN i XMAX
analogicznie pare linijek nizej w cIm:
zaladowac XMIN i XMAX w odwrotnej kolejnosci

przy etykiecie rysuj:
po linijce

mov al, 10 

musi byc

jmp dalej2

a dalej2: ustawiam na linijce

mov byte ptr es:[di],al

Moze ktos to ruszy?? algorytm nie jest trudny i az tak duzo tego nie ma. Bede baaaardzo wdzieczny :)

pozdr.

0

juz sobie poradzilem
chcialem zrobic 2 kolorowe i nie wyszlo
jakby kogos interesowalo, to przed rysowaniem laduje tylko cx do akumulatora i to wszystko, zadne wybor koloru itd i dziala ladnie (chociaz nie rozumiem, czemu przedtem to nie szlo :/)

sorki za zamieszanie, chociaz i tak szczerze watpie, ze ktos to sprobowal ruszyc :p

1 użytkowników online, w tym zalogowanych: 0, gości: 1