offset equ 256 unity equ 16777216 colors equ 256 height equ 512 width equ 512 startx equ -2 starty equ -2 endx equ 2 endy equ 2 constant equ unity beginx equ startx*unity+(158*131072) beginy equ starty*unity+(285*131072) stepx equ (endx-startx)*unity/width/64 stepy equ (endy-starty)*unity/height/64 gastonx equ beginx+(261*2048) gastony equ beginy+(345*2048) jmp start words: db 13,"*************************" db 13,10,"* WEHNER`s *" db 13,10,"* OWLBROT FRACTAL MAKER *" db 13,10,"* COPYRIGHT 2006 *" db 13,10,"* WIDTH 512 PIXELS *" db 13,10,"* HEIGHT 512 PIXELS *" db 13,10,"* START -0.765625 *" db 13,10,"* +0.2265625 *" db 13,10,"* STEP 2048 *" db 13,10,"* 2048 *" db 13,10,"* FINISH -0.703125 *" db 13,10,"* +0.2890625 *" db 13,10,"* VECTOR -0.733764648 *" db 13,10,"* +0.268676757 *" db 13,10,"*************************",13,10,"$",26 header: db 066,077,054,004,004,000,000,000,000,000,054,004,000,000,040,000 ;;;BM6.......6...(. db 000,000 dd width ; 000,002,000,000 for 512 dd height ; 000,002,000,000 for 512 db 001,000,008,000,000,000 db 000,000,000,000,004,000,000,000,000,000,000,000,000,000,000,001 db 000,000,000,001,000,000 palette: db 255,255,255,000,249,255,249,000,243,255 db 243,000,237,255,237,000,231,255,231,000,225,255,225,000,219,255 db 219,000,213,255,213,000,207,255,207,000,201,255,201,000,195,255 db 195,000,189,255,189,000,183,255,183,000,177,255,177,000,171,255 db 171,000,165,255,165,000,159,255,159,000,153,255,153,000,147,255 db 147,000,141,255,141,000,135,255,135,000,128,255,128,000,122,255 db 131,000,116,255,134,000,110,255,137,000,104,255,140,000,098,255 db 143,000,092,255,146,000,086,255,149,000,080,255,152,000,074,255 db 155,000,068,255,158,000,062,255,161,000,056,255,164,000,050,255 db 167,000,044,255,170,000,038,255,173,000,032,255,176,000,026,255 db 179,000,020,255,182,000,014,255,185,000,008,255,189,000,000,255 db 189,000,000,252,205,000,000,249,211,000,000,246,217,000,000,243 db 223,000,000,240,229,000,000,237,235,000,000,231,238,000,000,225 db 243,000,000,219,246,000,000,213,249,000,000,207,252,000,000,201 db 255,000,000,195,255,000,000,189,255,000,000,183,255,000,000,177 db 255,000,000,171,255,000,000,165,255,000,000,159,255,000,000,153 db 255,000,000,147,255,000,000,141,255,000,000,135,255,000,000,128 db 255,000,000,122,255,000,000,116,255,000,000,110,255,000,000,104 db 255,000,000,098,255,000,000,092,255,000,000,086,255,000,000,082 db 255,000,000,076,255,000,000,070,255,000,000,064,255,000,000,058 db 255,000,000,052,255,000,000,046,255,000,000,040,255,000,000,034 db 255,000,000,028,255,000,000,022,255,000,000,016,255,000,000,010 db 255,000,000,004,255,000,000,000,255,000,006,000,255,000,012,000 db 255,000,018,000,255,000,024,000,255,000,030,000,255,000,036,000 db 255,000,042,000,255,000,048,000,255,000,054,000,255,000,060,000 db 255,000,066,000,255,000,072,000,255,000,078,000,255,000,084,000 db 255,000,090,000,255,000,096,000,255,000,102,000,255,000,108,000 db 255,000,114,000,255,000,120,000,255,000,128,000,255,000,134,000 db 255,000,140,000,255,000,146,000,255,000,152,000,255,000,158,000 db 255,000,164,000,255,000,170,000,255,000,176,000,255,000,182,000 db 255,000,188,000,255,000,194,000,255,000,200,000,255,000,206,000 db 255,000,212,000,255,000,218,000,255,000,224,000,255,000,230,000 db 255,000,236,000,255,000,242,000,255,000,248,000,255,000,255,000 db 255,000,255,000,252,000,255,000,246,000,255,000,240,000,255,000 db 234,000,255,000,228,000,255,000,222,000,255,000,216,000,255,000 db 210,000,255,000,204,000,255,000,198,000,255,000,192,000,255,000 db 186,000,255,000,180,000,255,000,174,000,255,000,168,000,255,000 db 162,000,255,000,156,000,255,000,150,000,255,000,146,000,255,000 db 140,000,255,000,134,000,255,000,128,000,255,000,122,000,255,000 db 116,000,255,000,110,000,255,000,104,000,255,000,098,000,255,000 db 092,000,255,000,086,000,255,000,080,000,255,000,074,000,255,000 db 068,000,255,000,062,000,255,000,056,000,255,000,050,000,255,000 db 044,000,255,000,038,000,255,000,032,000,255,000,026,000,255,000 db 020,000,255,000,014,000,255,000,008,000,255,000,000,000,255,006 db 000,000,255,012,000,000,255,018,000,000,255,024,000,000,255,030 db 000,000,255,036,000,000,255,042,000,000,255,048,000,000,255,054 db 000,000,255,060,000,000,255,066,000,000,255,072,000,000,255,078 db 000,000,255,084,000,000,255,090,000,000,255,096,000,000,255,102 db 000,000,255,108,000,000,255,114,000,000,255,120,000,000,255,128 db 000,000,249,128,000,000,243,128,000,000,237,128,000,000,231,128 db 000,000,225,128,000,000,219,128,000,000,213,128,000,000,207,128 db 000,000,201,128,000,000,195,128,000,000,189,128,000,000,183,128 db 000,000,177,128,000,000,171,128,000,000,165,128,000,000,159,128 db 000,000,153,128,000,000,147,128,000,000,141,128,000,000,135,128 db 000,000,128,128,000,000,122,128,000,000,116,128,000,000,110,128 db 000,000,104,128,000,000,098,128,000,000,092,128,000,000,086,128 db 000,000,080,128,000,000,076,128,000,000,070,128,000,000,064,128 db 000,000,058,128,000,000,052,128,000,000,046,128,000,000,040,128 db 000,000,034,128,000,000,028,128,000,000,022,128,000,000,016,128 db 000,000,010,128,000,000,004,128,000,000,000,128,000,000,006,122 db 006,000,012,116,012,000,018,110,018,000,024,104,024,000,030,098 db 030,000,036,092,036,000,042,086,042,000,048,080,048,000,054,074 db 064,000,060,068,060,000,064,064,064,000,056,056,056,000,048,048 db 048,000,040,040,040,000,032,032,032,000,024,024,024,000,012,012 db 012,000,000,000,000,000 dest: ; File handle of destination file dw 0 dump: ; When dumping to disk, how many bytes dw 0 ; TOGETHER dumpseg: ; When dumping to disk, how many 32Ks dw 0 linepos: ; When printing "LINE NUMBER", last char dw linenoend+offset-2 mandelx: ; The real part of Zo times 16777216 dd beginx mandely: ; The unreal part of Zo times 16777216 dd beginy juliax: ; The real part of Z times 16777216 dd 0 juliay: ; The unreal part of Z times 16777216 dd 0 tempxy: ; Temporary store for X or Y dd 0,0 tempxy2: ; Another temporary store for X or Y dd 0,0 mandpix: ; The pixel (byte) being evaluated dw 0 mandseg: ; The segment in which "mandpix" is dw 0 preresx: db 0,0,0 resx dd 0 db 0 preresy: db 0,0,0 resy dd 0 db 0 pretempx: db 0,0,0 tempx: dd 0 db 0 pretempy: db 0,0,0 tempy: dd 0 db 0 mierx dd 0 miery dd 0 filename: db "owl.bmp",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 destprob: db "OUTPUT FILE PROBLEM",13,10,"$" nocreate: db "CANNOT CREATE THE OWL.BMP FILE",13,10,"$" completed: db 13,10,"DONE. FILE OWL.BMP COMPLETED",13,10,"$" lineno: db 13,"LINE NUMBER $" db "00000$" linenoend: abort: mov ax,cs mov ds,ax mov es,ax mov ax,900h int 33 mov ah,76 int 33 writeline: mov dx,lineno+offset ; Display CR,"LINE NUMBER" mov ax,900h int 33 std mov si,linenoend+offset-2 mov di,linenoend+offset-2 linenoloop: lodsb inc al ; Increment the last number cmp al,"9"+1 jnc repeatno stosb mov dx,si inc dx cmp dx,[linepos+offset] ; If linepos is lower than before, jnc sayline mov [linepos+offset],dx ; put it into the variable. sayline: mov dx,[linepos+offset] ; Get the start of the number mov ax,900h ; and display. int 33 ret repeatno: ; If a number went beyond 9 mov al,"0" ; set it to 0 stosb jmp linenoloop ; and increment the previous. commult: mov eax,[mierx+offset] mov ebx,eax add ebx,ebx sbb ebx,ebx xor eax,ebx mov edx,[resx+offset] mov ecx,edx add ecx,ecx sbb ecx,ecx xor edx,ecx mul edx xor ebx,ecx xor edx,ebx xor eax,ebx mov [pretempx+offset],eax mov [pretempx+offset+4],edx mov eax,[miery+offset] mov ebx,eax add ebx,ebx sbb ebx,ebx xor eax,ebx mov edx,[resy+offset] mov ecx,edx add ecx,ecx sbb ecx,ecx xor edx,ecx mul edx xor ebx,ecx xor edx,ebx xor eax,ebx sub [pretempx+offset],eax sbb [pretempx+offset+4],edx mov eax,[mierx+offset] mov ebx,eax add ebx,ebx sbb ebx,ebx xor eax,ebx mov edx,[resy+offset] mov ecx,edx add ecx,ecx sbb ecx,ecx xor edx,ecx mul edx xor ebx,ecx xor edx,ebx xor eax,ebx mov [pretempy+offset],eax mov [pretempy+offset+4],edx mov eax,[miery+offset] mov ebx,eax add ebx,ebx sbb ebx,ebx xor eax,ebx mov edx,[resx+offset] mov ecx,edx add ecx,ecx sbb ecx,ecx xor edx,ecx mul edx xor ebx,ecx xor edx,ebx xor eax,ebx add [pretempy+offset],eax adc [pretempy+offset+4],edx mov eax,[tempx+offset] mov [resx+offset],eax mov eax,[tempy+offset] mov [resy+offset],eax ret start: mov dx,words+offset ; Display the title mov ax,900h int 33 mov dx,filename+offset xor cx,cx mov ax,3c00h ; Create the output file int 33 mov dx,nocreate+offset jc abort mov [dest+offset],ax mov ax,4000h ; Put in the header and palette mov bx,[dest+offset] mov cx,1078 mov dx,header+offset int 33 mov dx,destprob+offset jc abort mov eax,(height*width) ; Height*width in BYTES mov bx,ax and bx,32767 add eax,eax ; Upper is groups of 32k mov [dump+offset],eax ; DUMPSEG gets upper part. mov [dump+offset],bx ; DUMP gets modulus cld mov eax,0ffffffffh ; Highest palette value, 4 pixels mov cx,[dumpseg+offset] mov dx,cs add dx,(65536/16) ; Prepare for segment 64k above and cx,cx ; is CX nil? jz lastones blankloop: mov es,dx push cx mov cx,8192 ; Fill the buffer with 255s mov di,0 repz stosd ; Four at a time (d for DOUBLE) add dx,(32768/16) ; shift segment pointer pop cx loop blankloop lastones: mov cx,bx ; Fill the buffer with 255s and cx,cx jz nolast mov es,dx mov di,0 repz stosb ; One at a time (b for BYTE) nolast: mov dx,cs mov es,dx mov ax,0 ; Start off pixel address mov [mandpix+offset],ax mov ax,cs ; Start off pixel segment add ax,(65536/16) mov [mandseg+offset],ax ;************************ MAIN ROUTINE HERE ******************** mov cx,height ; Prepare for a loop of HEIGHT lines. lineloop: push cx mov cx,width ; Prepare for a loop of WIDTH pixels. dotloop: push cx ; Save the pixels-per-row counter mov cx,colors ; For each dot, COLORS iterations. mov eax,[mandelx+offset] ; Mandel X (Xo) mov [juliax+offset],eax ; is the first X mov eax,[mandely+offset] ; Mandel Y (Yo) mov [juliay+offset],eax ; is the first Y chaosloop: mov eax,[juliax+offset] ; Working on X mov edx,eax add edx,edx ; Signum into carry sbb edx,edx ; Signum is FFFFFFFF or 0 xor eax,edx ; (Cancel the signum) mul eax ; Multiply absolute X by absolute X mov ebx,edx mov eax,[juliay+offset] ; Working on Y mov edx,eax add edx,edx ; Signum into carry sbb edx,edx ; Signum is FFFFFFFF or 0 xor eax,edx ; (Cancel the signum) mul eax ; Multiply absolute Y by absolute Y add edx,ebx dec cx jz bail ; If count expired, jump out. cmp edx,4*unity jc nobailout ; If xsq + ysq >= 4, jump out. bail: jmp bailout nobailout: push cx mov eax,[juliax+offset] ; Working on JULIA X mov [resx+offset],eax mov [mierx+offset],eax mov eax,[juliay+offset] mov [resy+offset],eax mov [miery+offset],eax call commult mov eax,[resx+offset] mov [mierx+offset],eax mov eax,[resy+offset] mov [miery+offset],eax call commult mov eax,[resx+offset] mov [mierx+offset],eax mov eax,[resy+offset] mov [miery+offset],eax call commult mov eax,[resx+offset] add eax,gastonx mov [juliax+offset],eax mov eax,[resy+offset] add eax,gastony mov [juliay+offset],eax pop cx jmp chaosloop bailout: not cl ;******** MANDELBROT PLOTTING ****************** mov ax,[mandseg+offset] ; Segment mov bx,[mandpix+offset] ; and the offset into the picture mov es,ax ; Move the ES: segment pointer mov di,bx mov al,cl ; Countdown CL is the palette number stosb mov ax,cs ; Return ES to the code segment mov es,ax ;******** PLOTTING FINISHED ****************** mov eax,stepx ; Move the X position by the step add [mandelx+offset],eax mov ax,1 ; Increment the pixel count add [mandpix+offset],ax jnz nomoreseg mov ax,(65536/16) ; If above 65535, new segment add [mandseg+offset],ax nomoreseg: pop cx ; Rescue the column counter dec cx ; Count down jz writealine ; until finished. jmp dotloop writealine: call writeline ; Say "LINE NUMBER" mov eax,stepy ; Move the Y position by the step add [mandely+offset],eax mov eax,beginx ; Start a new row mov [mandelx+offset],eax pop cx ; Rescue the row counter dec cx ; Count down jz leavemand ; until finished. jmp lineloop leavemand: ;************************ MAIN ROUTINE ENDS ******************** mov cx,[dumpseg+offset] mov bx,ds add bx,(65536/16) ; Prepare for source 64k up mov ds,bx loop32k: and cx,cx jz modulus push cx mov ax,4000h ; Put the picture onto disk (groups of 32k) mov bx,[cs:dest+offset] mov cx,32768 mov dx,0 int 33 mov dx,destprob+offset jc abort mov ax,ds add ax,(32768/16) mov ds,ax pop cx dec cx jmp loop32k modulus: mov cx,[cs:dump+offset] and cx,cx jz finished mov ax,4000h ; Put the picture onto disk (remainder) mov bx,[cs:dest+offset] mov dx,0 int 33 mov dx,destprob+offset jc abort finished: mov ax,cs mov ds,ax mov ax,3e00h ; Close the file mov bx,[dest+offset] int 33 mov dx,completed+offset ; Say that it is done. mov ah,9 int 33 mov ah,76 int 33 int 32 END