Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2659 | leency | 1 | ; App written by randall ported to Kolibri and MenuetOS64 by macgub (www.macgub.hekko.pl). |
2 | ; Now it use static memory, it is mixed 32bit code and SSE instructions. |
||
3 | |||
4 | include '../../../macros.inc' |
||
5 | |||
6 | use32 |
||
7 | |||
8 | org 0x0 |
||
9 | |||
10 | db 'MENUET01' ; 8 byte id |
||
11 | dd 0x01 ; header version |
||
12 | dd START ; start of code |
||
13 | dd IMG_END ; size of image |
||
14 | dd I_END ;0x100000 ; memory for app |
||
15 | dd I_END ;0xbffff ; esp |
||
16 | dd 0x0 , 0x0 ; I_Param , I_Icon |
||
17 | |||
18 | START: ; start of execution |
||
19 | |||
20 | call draw_window |
||
21 | call Main |
||
22 | call draw_from_buffer |
||
23 | |||
24 | still: |
||
25 | |||
26 | |||
27 | ; call Main |
||
28 | |||
29 | |||
30 | ; mov eax,7 |
||
31 | ; mov ebx,screen |
||
32 | ; mov ecx,IMG_SIZE*65536+IMG_SIZE |
||
33 | ; mov edx,0*65536+0 |
||
34 | ; int 0x40 |
||
35 | |||
36 | ; mov eax,23 ; wait here for event |
||
37 | ; mov ebx,timeout |
||
38 | ; int 0x40 |
||
39 | ; mov eax,11 ; check for event no wait |
||
40 | mov eax,10 ; wait for event |
||
41 | int 0x40 |
||
42 | |||
43 | cmp eax,1 ; redraw request ? |
||
44 | je red |
||
45 | cmp eax,2 ; key in buffer ? |
||
46 | je key |
||
47 | cmp eax,3 ; button in buffer ? |
||
48 | je button |
||
49 | |||
50 | jmp noclose |
||
51 | |||
52 | red: ; redraw |
||
53 | call draw_window |
||
54 | call draw_from_buffer |
||
55 | jmp still |
||
56 | |||
57 | key: ; key |
||
58 | mov eax,2 ; just read it and ignore |
||
59 | int 0x40 |
||
60 | shr eax,8 |
||
61 | cmp eax, 27 |
||
62 | jne still |
||
63 | mov eax, -1 |
||
64 | int 0x40 |
||
65 | |||
66 | |||
67 | button: ; button |
||
68 | mov eax,17 ; get id |
||
69 | int 0x40 |
||
70 | |||
71 | cmp ah,1 ; button id=1 ? |
||
72 | jne noclose |
||
73 | |||
74 | mov eax,-1 ; close this program |
||
75 | int 0x40 |
||
76 | noclose: |
||
77 | |||
78 | jmp still |
||
79 | |||
80 | |||
81 | draw_from_buffer: |
||
82 | |||
83 | mov eax,7 |
||
84 | mov ebx,screen |
||
85 | mov ecx,IMG_SIZE*65536+IMG_SIZE |
||
86 | mov edx,0*65536+0 |
||
87 | int 0x40 |
||
88 | ret |
||
89 | |||
90 | ;------------------------------------------------------------------------------- |
||
91 | ; NAME: XORWOW |
||
92 | ; DESC: Pseudo random number generator. |
||
93 | ; OUT: eax [0;2^32-1] |
||
94 | ;------------------------------------------------------------------------------- |
||
95 | macro XORWOW { |
||
96 | mov edx,[g_xorwow_x] ; edx = x |
||
97 | shr edx,2 ; edx = x >> 2 |
||
98 | xor edx,[g_xorwow_x] ; t = x ^ (x >> 2) |
||
99 | mov eax,[g_xorwow_y] ; eax = y |
||
100 | mov [g_xorwow_x],eax ; x = y |
||
101 | mov eax,[g_xorwow_z] ; eax = z |
||
102 | mov [g_xorwow_y],eax ; y = z |
||
103 | mov eax,[g_xorwow_w] ; eax = w |
||
104 | mov [g_xorwow_z],eax ; z = w |
||
105 | mov eax,[g_xorwow_v] ; eax = v |
||
106 | mov [g_xorwow_w],eax ; w = v |
||
107 | mov edi,eax ; edi = v |
||
108 | shl edi,4 ; edi = v << 4 |
||
109 | xor edi,eax ; edi = (v ^ (v << 4)) |
||
110 | mov eax,edx ; eax = t |
||
111 | shl eax,1 ; eax = t << 1 |
||
112 | xor eax,edx ; eax = (t ^ (t << 1)) |
||
113 | xor eax,edi ; eax = (v ^ (v << 4)) ^ (t ^ (t << 1)) |
||
114 | mov [g_xorwow_v],eax ; v = eax |
||
115 | add [g_xorwow_d],362437 ; d += 362437 |
||
116 | mov eax,[g_xorwow_d] ; eax = d |
||
117 | add eax,[g_xorwow_v] ; eax = d + v |
||
118 | } |
||
119 | ;------------------------------------------------------------------------------- |
||
120 | ; NAME: RANDOM |
||
121 | ; DESC: Returns pseudo random number in the range [-0.5;0.5). |
||
122 | ; OUT: xmm0.x [-0.5;0.5) |
||
123 | ;------------------------------------------------------------------------------- |
||
124 | macro RANDOM { |
||
125 | XORWOW |
||
126 | cvtsi2ss xmm0,eax |
||
127 | mulss xmm0,[g_rand_scale] |
||
128 | } |
||
129 | ;------------------------------------------------------------------------------- |
||
130 | |||
131 | ;------------------------------------------------------------------------------- |
||
132 | ; NAME: GenerateSequence |
||
133 | ; IN: xmm0.x re (c0.x) |
||
134 | ; IN: xmm1.x im (c0.y) |
||
135 | ; IN: edi array size |
||
136 | ; IN/OUT: esi pointer to the allocated array |
||
137 | ; OUT: eax generated sequence size |
||
138 | ;------------------------------------------------------------------------------- |
||
139 | align 16 |
||
140 | GenerateSequence: |
||
141 | xor eax,eax ; eax is index loop |
||
142 | xorps xmm4,xmm4 ; xmm4 is c.x |
||
143 | xorps xmm5,xmm5 ; xmm5 is c.y |
||
144 | .Loop: |
||
145 | ; cn.x = c.x * c.x - c.y * c.y + c0.x |
||
146 | movaps xmm2,xmm4 |
||
147 | movaps xmm3,xmm5 |
||
148 | mulss xmm2,xmm4 |
||
149 | mulss xmm3,xmm5 |
||
150 | subss xmm2,xmm3 |
||
151 | addss xmm2,xmm0 |
||
152 | movaps xmm6,xmm2 ; xmm6 is cn.x |
||
153 | ; cn.y = 2.0 * c.x * c.y + c0.y |
||
154 | movaps xmm7,xmm4 |
||
155 | mulss xmm7,xmm5 |
||
156 | addss xmm7,xmm7 |
||
157 | addss xmm7,xmm1 ; xmm7 is cn.y |
||
158 | ; store cn |
||
159 | movd dword [esi+eax*8],xmm6 |
||
160 | movd dword [esi+eax*8+4],xmm7 |
||
161 | ; if (cn.x * cn.x + cn.y * cn.y > 10.0) return eax; |
||
162 | movaps xmm2,xmm6 |
||
163 | movaps xmm3,xmm7 |
||
164 | mulss xmm2,xmm6 |
||
165 | mulss xmm3,xmm7 |
||
166 | addss xmm2,xmm3 |
||
167 | ucomiss xmm2,[g_max_dist] |
||
168 | ja .EndLoop |
||
169 | movaps xmm4,xmm6 ; c.x = cn.x |
||
170 | movaps xmm5,xmm7 ; c.y = cn.y |
||
171 | ; continue loop |
||
172 | inc eax |
||
173 | cmp eax,edi |
||
174 | jb .Loop |
||
175 | ; return 0 |
||
176 | xor eax,eax |
||
177 | .EndLoop: |
||
178 | ret |
||
179 | ;------------------------------------------------------------------------------- |
||
180 | ; NAME: main |
||
181 | ; DESC: Program main function. |
||
182 | ;------------------------------------------------------------------------------- |
||
183 | align 16 |
||
184 | Main: |
||
185 | img_ptr equ ebp-8 |
||
186 | seq_ptr equ ebp-16 |
||
187 | pixel equ ebp-24 |
||
188 | r13dd equ ebp-64 |
||
189 | r12dd equ ebp-68 |
||
190 | r15dd equ ebp-72 |
||
191 | |||
192 | push ebp |
||
193 | mov ebp,esp |
||
194 | sub esp,128 |
||
195 | ; mem for the sequence |
||
196 | lea eax,[sequence] |
||
197 | mov [seq_ptr],eax |
||
198 | ; mem for the image |
||
199 | lea eax,[screen] |
||
200 | mov [img_ptr],eax |
||
201 | ; begin loops |
||
202 | mov dword[r13dd],0 ; .LoopIterations counter |
||
203 | .LoopIterations: |
||
204 | mov dword[r12dd],0 ; .LoopOneMillion counter |
||
205 | .LoopOneMillion: |
||
206 | RANDOM |
||
207 | mulss xmm0,[g_range] |
||
208 | movaps xmm1,xmm0 |
||
209 | RANDOM |
||
210 | mulss xmm0,[g_range] |
||
211 | mov edi,SEQ_SIZE |
||
212 | mov esi,[seq_ptr] |
||
213 | call GenerateSequence ; eax = n sequence size |
||
214 | test eax,eax |
||
215 | jz .LoopSequenceEnd |
||
216 | xor ecx,ecx ; ecx = i = 0 loop counter |
||
217 | ; mov r9dd,[seq_ptr] ; r9 = sequence base address |
||
218 | ; mov r8dd,[img_ptr] ; r8 = image base address |
||
219 | movss xmm2,[g_img_size] |
||
220 | movaps xmm3,xmm2 |
||
221 | mulss xmm3,[g_0_5] ; xmm3 = (g_img_size)/2 |
||
222 | movss xmm4,[g_zoom] |
||
223 | mulss xmm4,xmm2 ; xmm4 = g_zoom * g_img_size |
||
224 | movss xmm5,[g_offsetx] ; xmm5 = g_offsetx |
||
225 | movss xmm6,[g_offsety] ; xmm6 = g_offsety |
||
226 | .LoopSequence: |
||
227 | cmp ecx,eax ; i < n |
||
228 | je .LoopSequenceEnd |
||
229 | movd xmm0,[sequence+ecx*8] ; load re |
||
230 | movd xmm1,[sequence+ecx*8+4] ; load im |
||
231 | addss xmm0,xmm5 ; xmm0 = re+g_offsetx |
||
232 | addss xmm1,xmm6 ; xmm1 = im+g_offsety |
||
233 | mulss xmm0,xmm4 ; xmm0 = (re+g_offsetx)*g_img_size*g_zoom |
||
234 | mulss xmm1,xmm4 ; xmm1 = (im+g_offsety)*g_img_size*g_zoom |
||
235 | addss xmm0,xmm3 ; xmm0 = (re+g_offsetx)*g_img_size*g_zoom+g_img_size/2 |
||
236 | addss xmm1,xmm3 ; xmm1 = (im+g_offsety)*g_img_size*g_zoom+g_img_size/2 |
||
237 | cvtss2si edi,xmm0 ; edi = x = int(xmm0.x) |
||
238 | cvtss2si esi,xmm1 ; esi = y = int(xmm1.x) |
||
239 | cmp edi,0 |
||
240 | jl @f |
||
241 | cmp edi,IMG_SIZE |
||
242 | jge @f |
||
243 | cmp esi,0 |
||
244 | jl @f |
||
245 | cmp esi,IMG_SIZE |
||
246 | jge @f |
||
247 | imul esi,esi,IMG_SIZE |
||
248 | add esi,edi |
||
249 | add dword [screen+esi*4],1 |
||
250 | @@: |
||
251 | inc ecx |
||
252 | jmp .LoopSequence |
||
253 | .LoopSequenceEnd: |
||
254 | ; continue .LoopOneMillion |
||
255 | add dword[r12dd],1 |
||
256 | cmp dword[r12dd],1000000 |
||
257 | jb .LoopOneMillion |
||
258 | ; continue .LoopIterations |
||
259 | add dword[r13dd],1 |
||
260 | cmp dword[r13dd],ITERATIONS |
||
261 | jb .LoopIterations |
||
262 | ; find max value |
||
263 | mov dword[r12dd],0 |
||
264 | xor eax,eax ; eax = i = loop counter |
||
265 | .LoopMax: |
||
266 | push ecx |
||
267 | mov ecx,[r12dd] |
||
268 | cmp dword [screen+eax*4],ecx |
||
269 | cmova ecx,dword [screen+eax*4] |
||
270 | mov [r12dd],ecx |
||
271 | pop ecx |
||
272 | inc eax |
||
273 | cmp eax,IMG_SIZE*IMG_SIZE |
||
274 | jb .LoopMax |
||
275 | ; find min value |
||
276 | ; mov r13d,r12d ; r13d = min_val = max_val |
||
277 | push dword[r12dd] |
||
278 | pop dword[r13dd] |
||
279 | xor eax,eax ; eax = i = loop counter |
||
280 | .LoopMin: |
||
281 | push ecx |
||
282 | mov ecx,[r13dd] |
||
283 | cmp dword [screen+eax*4],ecx |
||
284 | |||
285 | cmovb ecx,dword [screen+eax*4] |
||
286 | mov [r13dd],ecx |
||
287 | pop ecx |
||
288 | inc eax |
||
289 | cmp eax,IMG_SIZE*IMG_SIZE |
||
290 | jb .LoopMin |
||
291 | ; write image pixels |
||
292 | mov byte [pixel+3],255 |
||
293 | ; mov r14,[img_ptr] ; r14 = image base address |
||
294 | ; xor r15d,r15d ; r15d = i = loop counter |
||
295 | mov dword[r15dd],0 |
||
296 | cvtsi2ss xmm0,[r12dd] ; load max_value |
||
297 | cvtsi2ss xmm1,[r13dd] ; load min_value |
||
298 | movaps xmm2,xmm0 |
||
299 | subss xmm2,xmm1 ; xmm2 = r = max_value - min_value |
||
300 | xor ecx,ecx |
||
301 | .LoopWrite: |
||
302 | mov eax,[screen+ecx*4] ; eax = image_value |
||
303 | sub eax,[r13dd] ; eax = image_value - min_value |
||
304 | cvtsi2ss xmm0,eax ; xmm0 = float(image_value - min_value) |
||
305 | addss xmm0,xmm0 ; xmm0 = 2.0f * float(image_value - min_value) |
||
306 | divss xmm0,xmm2 ; xmm0 = 2.0f * float(image_value - min_value) / r |
||
307 | minss xmm0,[g_1_0] ; clamp to 1.0 |
||
308 | maxss xmm0,[g_0_0] ; clamp to 0.0 |
||
309 | mulss xmm0,[g_255_0] ; convert to 0 - 255 |
||
310 | cvtss2si eax,xmm0 |
||
311 | ; write pixel data |
||
312 | mov [screen+ecx*3],eax |
||
313 | inc ecx |
||
314 | cmp ecx,IMG_SIZE*IMG_SIZE |
||
315 | jb .LoopWrite |
||
316 | mov esp,ebp |
||
317 | pop ebp |
||
318 | ret |
||
319 | ; restore img_ptr,seq_ptr,pixel |
||
320 | ;------------------------------------------------------------------------------- |
||
321 | ; ********************************************* |
||
322 | ; ******* WINDOW DEFINITIONS AND DRAW ******** |
||
323 | ; ********************************************* |
||
324 | draw_window: |
||
325 | |||
326 | mcall 12, 1 ; function 12:tell os about windowdraw |
||
327 | |||
328 | mcall 48, 4 ;get skin width |
||
329 | lea ecx, [50*65536+IMG_SIZE+4+eax] ; [y start] *65536 + [y size] + [skin_height] |
||
330 | mcall 0,<50,IMG_SIZE+9>,,0x74000000,,labelt ;draw window |
||
331 | |||
332 | mcall 12, 2 ; function 12:tell os about windowdraw |
||
333 | |||
334 | ret |
||
335 | |||
336 | |||
337 | |||
338 | ;------------------------------------------------------------------------------- |
||
339 | align 1 |
||
340 | labelt: |
||
341 | db 'buddhabrot',0 |
||
342 | labelen: |
||
343 | |||
344 | align 4 |
||
345 | g_xorwow_x dd 123456789 |
||
346 | g_xorwow_y dd 362436069 |
||
347 | g_xorwow_z dd 521288629 |
||
348 | g_xorwow_w dd 88675123 |
||
349 | g_xorwow_v dd 5783321 |
||
350 | g_xorwow_d dd 6615241 |
||
351 | g_rand_scale dd 2.3283064e-10 ; 1.0 / 2^32 |
||
352 | |||
353 | IMG_SIZE=600 |
||
354 | SEQ_SIZE=50 |
||
355 | ITERATIONS=100 |
||
356 | g_img_size dd 600.0 |
||
357 | g_offsetx dd 0.5 |
||
358 | g_offsety dd 0.0 |
||
359 | g_zoom dd 0.4 |
||
360 | |||
361 | g_max_dist dd 10.0 |
||
362 | g_range dd 4.2 |
||
363 | g_0_5 dd 0.5 |
||
364 | g_0_0 dd 0.0 |
||
365 | g_1_0 dd 1.0 |
||
366 | g_255_0 dd 255.0 |
||
367 | |||
368 | IMG_END: |
||
369 | ;-------------------- |
||
370 | sequence: |
||
371 | rb SEQ_SIZE*8 |
||
372 | screen: |
||
373 | rb IMG_SIZE*IMG_SIZE*4 |
||
374 | memStack: |
||
375 | rd 1024 |
||
376 | I_END:50,IMG_SIZE+9>>><>><>><>><>><>><> |