Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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: