Subversion Repositories Kolibri OS

Rev

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: