home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / landscap / landscap.asm < prev    next >
Assembly Source File  |  1994-12-10  |  13KB  |  794 lines

  1. ; =============================================================================
  2. ;
  3. ;    landscapes with *real* shading.
  4. ;
  5. ;    (C)94 xToto/Valhalla
  6. ;
  7. ;    first presented at the pc-party in herning/denmark
  8. ;
  9. ; =============================================================================
  10.  
  11.     .model large
  12.  
  13.     .stack 100h
  14.  
  15. Xsin_base = 8    ; we get sin_values values in 0..pi/2
  16. Xsin_values = 1 shl Xsin_base
  17.  
  18. Xlayers = 13
  19.  
  20. _data segment public 'data'
  21.     Xstart    dw 0h+200h, 1f8h+200h, -208h+200h, -400h+200h
  22.     Xcolsk    dw 4h, 200h, -4h, -200h
  23.     Xrowsk    dw 4h, 1fch, -4h, -1fch
  24.     Xvga    dw 003d4h
  25.         dw 00e11h
  26.         dw 00d06h
  27.         dw 03e07h
  28.         dw 0c109h
  29.         dw 0ea10h
  30.         dw 0df12h
  31.         dw 02813h
  32.         dw 0e715h
  33.         dw 00616h
  34.         dw -1
  35.         dw -1
  36.     Xpoint0    dw  03e00h, -03e00h
  37.         dw  03e00h,  03e00h
  38.         dw -03e00h,  03e00h
  39.         dw -03e00h, -03e00h
  40.     Xphase    dw 0
  41.     Xtimer    dw 0
  42.     Xsrand    dw 31237
  43.     Xoffset dw 0
  44.     Xsun_x    db ?
  45.     Xsun_y    db ?
  46.     Xsun_z    db ?
  47.     Xdx    dw ?
  48.     Xdx3    dw ?
  49.     Xddx    dw ?
  50.     Xdy    dw ?
  51.     Xdy3    dw ?
  52.     Xddy    dw ?
  53.     Xx0    dw ?
  54.     Xx1    dw ?
  55.     Xx2    dw ?
  56.     Xx3    dw ?
  57.     Xy0    dw ?
  58.     Xy1    dw ?
  59.     Xy2    dw ?
  60.     Xy3    dw ?
  61.     Xh1    dw ?
  62.     Xh2    dw ?
  63.     Xh3    dw ?
  64.     Xsins    dw Xsin_values dup (?)
  65.     Xcoss    dw Xsin_values dup (?)
  66.     Xsins2    dw Xsin_values dup (?)
  67.     Xcoss2    dw Xsin_values dup (?)
  68.     Xsins3    dw Xsin_values dup (?)
  69.     Xfstart    dw Xlayers dup (?)
  70.     Xfdx    dw Xlayers dup (?)
  71.     Xfdy    dw Xlayers dup (?)
  72.     Xhght1    dd 128 dup (?)
  73.     Xhght2    dd 128 dup (?)
  74. _data ends
  75.  
  76. _landscape segment public 'bss'
  77.     dw    08000h dup (?)
  78. _landscape ends
  79.  
  80. _buffer segment public 'bss'
  81.     dw    08000h dup (?)
  82. _buffer ends
  83.  
  84. _fastmul segment public 'bss'
  85.     dw    08000h dup (?)
  86. _fastmul ends
  87.  
  88. _sun segment public 'code'
  89.     assume cs:_sun; ds:_data; es:_landscape; fs:_buffer; gs:nothing
  90.     .386
  91.  
  92. ; clean up what needs to be cleaned up
  93. ; used registers: ax
  94.  
  95. Xclean_up:
  96.     mov    ax, 0003h
  97.     int    10h
  98.     ret
  99.  
  100. ; build the landscape (draw it into fs)
  101. ; used registers: all ?
  102.  
  103. Xbuild:
  104.     mov    ax, seg _fastmul    ; use mul-lookup
  105.     mov    gs, ax
  106.     mov    bx, Xphase
  107.     add    bx, bx
  108.     mov    ax, Xstart[bx]
  109.     add    ax, Xoffset
  110.     mov    word ptr cs:Xbuild_start-2, ax
  111.     mov    ax, Xrowsk[bx]
  112.     mov    word ptr cs:Xbuild_row_skip-2, ax
  113.     mov    ax, Xcolsk[bx]
  114.     mov    word ptr cs:Xbuild_col_skip-2, ax
  115.     mov    al, Xsun_x
  116.     mov    byte ptr cs:Xbuild_sun_x-1, al
  117.     mov    al, Xsun_y
  118.     mov    byte ptr cs:Xbuild_sun_y-1, al
  119.     mov    al, Xsun_z
  120.     mov    byte ptr cs:Xbuild_sun_z-1, al
  121.     mov    ax, Xx2
  122.     sub    ax, Xx3
  123.     mov    Xdx, ax
  124.     mov    bx, Xx1
  125.     mov    cx, Xx0
  126.     sub    bx, cx
  127.     sub    cx, Xx3
  128.     sar    cx, 6
  129.     mov    Xdx3, cx
  130.     sub    bx, ax
  131.     sar    bx, 6
  132.     mov    Xddx, bx
  133.  
  134.     mov    ax, Xy2
  135.     mov    dx, Xy3
  136.     sub    ax, dx
  137.     mov    Xdy, ax
  138.     mov    bx, Xy1
  139.     mov    cx, Xy0
  140.     sub    bx, cx
  141.     sub    cx, dx
  142.     sar    cx, 6
  143.     mov    Xdy3, cx
  144.     sub    bx, ax
  145.     sar    bx, 6
  146.     mov    Xddy, bx
  147.  
  148.     mov    cx, Xx3
  149.     add    cx, cx
  150.     add    dx, dx
  151.     xor    ch, 80h
  152.     xor    dh, 80h
  153.     mov    ax, Xdx
  154.     mov    bx, Xdy
  155.     mov    di, 1234h
  156. Xbuild_start:
  157.     mov    bp, 007fh
  158. Xbuild_loop2:
  159.     mov    ax, Xx3
  160.     sub    ax, Xx0
  161.     imul    bp
  162.     shrd    ax, dx, 7
  163.     add    ax, Xx0
  164.     mov    cx, ax
  165.     mov    ax, Xx2
  166.     sub    ax, Xx1
  167.     imul    bp
  168.     shrd    ax, dx, 7
  169.     add    ax, Xx1
  170.     sub    ax, cx
  171.     sar    ax, 6
  172.     mov    word ptr cs:[offset Xbuild_inc1 + 2], ax
  173.     add    cx, cx
  174.     add    ch, 80h
  175.  
  176.     mov    ax, Xy3
  177.     sub    ax, Xy0
  178.     imul    bp
  179.     shrd    ax, dx, 7
  180.     add    ax, Xy0
  181.     mov    bx, ax
  182.     mov    ax, Xy2
  183.     sub    ax, Xy1
  184.     imul    bp
  185.     shrd    ax, dx, 7
  186.     add    ax, Xy1
  187.     sub    ax, bx
  188.     sar    ax, 6
  189.     mov    word ptr cs:[offset Xbuild_inc2 + 2], ax
  190.     mov    dx, bx
  191.     add    dx, dx
  192.     add    dh, 80h
  193.     push    bp
  194.  
  195.     mov    bp, 007fh
  196. Xbuild_loop1:
  197.     mov    bh, dh
  198.     mov    bl, ch
  199.     sub    bh, es:[di]
  200.     mov    si, bx
  201.     xor    bh, bh
  202.     mov    bl, es:[di+1]
  203.     mov    al, gs:[bx+0100h]
  204. Xbuild_sun_x:
  205.     mov    bl, es:[di+2]
  206.     add    al, gs:[bx+0100h]
  207. Xbuild_sun_y:
  208.     mov    bl, es:[di+3]
  209.     add    al, gs:[bx+0100h]
  210. Xbuild_sun_z:
  211.     mov    ah, al
  212.     add    di, 1234h
  213. Xbuild_col_skip:
  214.     mov    fs:[si], ax
  215.     mov    fs:[si+0100h], ax
  216.     mov    fs:[si+0200h], ax
  217.     mov    fs:[si+0300h], ax
  218.     mov    fs:[si+0400h], ax
  219. Xbuild_inc1:
  220.     add    cx, 01234h
  221. Xbuild_inc2:
  222.     add    dx, 01234h
  223.     dec    bp
  224.     jne    Xbuild_loop1
  225.     add    di, 1234h
  226. Xbuild_row_skip:
  227.     pop    bp
  228.     dec    bp
  229.     jne    Xbuild_loop2
  230.     ret
  231.  
  232. ; Xdump the buffer to the screen and clear the buffer
  233. ; used registers: all ?
  234.  
  235. Xdump:
  236.     mov    ax, 0a000h
  237.     mov    gs, ax
  238.     mov    si, 68*256+48
  239.     xor    di, di
  240.     mov    edx, 80808080h
  241.     mov    cx, 120
  242. Xdump1:
  243.     push    cx
  244.     mov    cx, 80
  245. Xdump2:
  246.     mov    bx, fs:[si]
  247.     mov    ah, bh
  248.     mov    al, bh
  249.     shl    eax, 16
  250.     mov    ah, bl
  251.     mov    al, bl
  252.     mov    gs:[di], eax
  253.     mov    fs:[si], dx
  254.     add    si, 2
  255.     add    di, 4
  256.     dec    cx
  257.     jnz    Xdump2
  258.     add    si, 96
  259.     pop    cx
  260.     dec    cx
  261.     jnz    Xdump1
  262.     ret
  263.  
  264. ; calculate a new row in the fractal (and store it at ds:di)
  265. ; used registers: all ?
  266.  
  267. Xmake_fractal:
  268.     mov    si, offset Xfstart
  269.     mov    bp, offset Xfdx
  270.     xor    eax, eax
  271.     mov    cx, 20h
  272. Xmake_fractal0:
  273.     mov    ds:[di], eax
  274.     mov    ds:[di+4], eax
  275.     mov    ds:[di+8], eax
  276.     mov    ds:[di+12], eax
  277.     add    di, 10h
  278.     dec    cx
  279.     jnz    Xmake_fractal0
  280.     sub    di, 200h
  281.     mov    cx, Xlayers
  282. Xmake_fractal1:
  283.     push    cx
  284.     mov    dx, ds:[bp]
  285.     mov    bx, [si]
  286.     mov    cx, 80h
  287. Xmake_fractal2:
  288.     movsx    eax, Xsins[bx]
  289.     add    ds:[di], eax
  290.     add    di, 4
  291.     add    bx, dx
  292.     and    bx, 8*Xsin_values-2
  293.     dec    cx
  294.     jnz    Xmake_fractal2
  295.     sub    di, 200h
  296.     add    si, 2
  297.     add    bp, 2
  298.     pop    cx
  299.     dec    cx
  300.     jnz    Xmake_fractal1
  301.     mov    cx, 80h
  302. Xmake_fractal3:
  303.     sar    dword ptr ds:[di], 5 ; ##
  304.     sub    word ptr ds:[di], 800h
  305.     add    di, 4
  306.     dec    cx
  307.     jnz    Xmake_fractal3
  308.     mov    si, offset Xfstart
  309.     mov    bp, offset Xfdy
  310.     mov    cx, Xlayers
  311. Xmake_fractal4:
  312.     mov    ax, ds:[bp]
  313.     add    ds:[si], ax
  314.     and    word ptr ds:[si], 8*Xsin_values-2
  315.     add    bp, 2
  316.     add    si, 2
  317.     dec    cx
  318.     jnz    Xmake_fractal4
  319.     ret
  320.  
  321. ; calculate the normals of the landscape
  322. ; used registers: all ?
  323.  
  324. Xget_normals:
  325.     mov    cx, 0080h
  326. Xget_normals1:
  327.     mov    ax, ds:[di+4]
  328.     sub    ax, ds:[di]
  329.     mov    Xh1, ax
  330.     mov    ax, -256
  331.     mov    Xh2, ax
  332.     mov    ax, ds:[di+200h]
  333. Xget_normals_last:
  334.     sub    ax, ds:[di]
  335.     mov    Xh3, ax
  336.     movsx    eax, Xh1
  337.     imul    eax
  338.     mov    esi, eax
  339.     movsx    eax, Xh2
  340.     imul    eax
  341.     add    esi, eax
  342.     movsx    eax, Xh3
  343.     imul    eax
  344.     add    eax, esi
  345.     push    bx
  346.     push    cx
  347.     push    di
  348.     call    Xsqrt
  349.     pop    di
  350.     pop    cx
  351.     pop    bx
  352.     mov    si, ax
  353.     mov    bp, ds:[di]
  354.     mov    ax, 80h
  355.     imul    Xh1
  356.     idiv    si
  357.     mov    es:[bx+1], al
  358.     mov    ax, 80h
  359.     imul    Xh2
  360.     idiv    si
  361.     mov    es:[bx+2], al
  362.     mov    ax, 80h
  363.     imul    Xh3
  364.     idiv    si
  365.     mov    es:[bx+3], al
  366.     mov    ax, bp
  367.     shr    ax, 8
  368.     mov    es:[bx], al
  369.     add    di, 4
  370.     add    bx, 4
  371.     dec    cx
  372.     jnz    Xget_normals1
  373.     neg    word ptr cs:Xget_normals_last-2
  374.     ret
  375.  
  376. ; Xinitialize everything that needs to be Xinitialized
  377. ; used registers: all ?
  378.  
  379. Xinit:
  380.     cld
  381.     mov    ax, seg _data        ; segment registers
  382.     mov    ds, ax
  383.     mov    ax, seg _landscape
  384.     mov    es, ax
  385.     mov    ax, seg _buffer
  386.     mov    fs, ax
  387.  
  388.     call    Xinit_gfx
  389.     call    Xinit_sin
  390.     call    Xinit_buffer
  391.     call    Xinit_fastmul
  392.     call    Xinit_fractal
  393.     ret
  394.  
  395. ; clear the buffer
  396. ; used registers:
  397.  
  398. Xinit_buffer:
  399.     xor    di, di
  400.     mov    edx, 80808080h
  401. Xinit_buffer1:
  402.     mov    fs:[di], edx
  403.     add    di, 4
  404.     jnz    Xinit_buffer1
  405.     ret
  406.  
  407. ; Initialize sin-waves for fourier transformation
  408. ; used registers: all ?
  409.  
  410. Xinit_fractal:
  411.     mov    si, offset Xfstart
  412.     mov    di, offset Xfdx
  413.     mov    bp, offset Xfdy
  414.     mov    cx, Xlayers
  415. Xinit_fractal1:
  416.     call    Xrand
  417.     and    ax, 4*Xsin_values-1
  418.     add    ax, ax
  419.     mov    [si], ax
  420.     call    Xrand
  421.     and    ax, 4*Xsin_values-1
  422.     add    ax, ax
  423.     mov    bx, ax
  424.     mov    ax, Xsins[bx]
  425.     sar    ax, 10
  426.     and    ax, -2
  427.     mov    [di], ax
  428.     mov    ax, Xcoss[bx]
  429.     sar    ax, 10
  430.     and    ax, -2
  431.     mov    ds:[bp], ax
  432.     add    si, 2
  433.     add    di, 2
  434.     add    bp, 2
  435.     dec    cx
  436.     jnz    Xinit_fractal1
  437.     mov    di, offset Xhght1
  438.     xor    eax, eax
  439.     mov    cx, 256
  440. Xinit_fractal2:
  441.     mov    ds:[di], eax
  442.     add    di, 4
  443.     dec    cx
  444.     jnz    Xinit_fractal2
  445.     xor    di, di
  446.     mov    cx, 4000h
  447.     rep    stosd
  448.     ret
  449.  
  450. ; switch to gfx-mode
  451. ; used registers: all ?
  452.  
  453. Xinit_gfx:
  454.     mov    ax, 0013h
  455.     int    10h
  456.     mov    si, offset Xvga        ; rewrite some vga-regisers
  457. Xinit_gfx2:
  458.     lodsw
  459.     cmp    ax, -1            ; is it all done ?
  460.     je    Xinit_gfx3
  461.     mov    dx, ax
  462. Xinit_gfx1:
  463.     lodsw
  464.     cmp    ax, -1            ; use next port ?
  465.     je    Xinit_gfx2
  466.     out    dx, ax
  467.     jmp    Xinit_gfx1
  468. Xinit_gfx3:
  469.     mov    dx, 03c2h        ; screen height: 100 -> 120
  470.     mov    al, 0e3h
  471.     out    dx, al
  472.     mov    dx, 03c8h
  473.     xor    al, al
  474.     out    dx, al
  475.     inc    dx
  476.     mov    cx, 00h
  477. Xinit_gfx4:
  478.     mov    al, cl
  479.     shr    al, 1h
  480.     out    dx, al
  481.     out    dx, al
  482.     out    dx, al
  483.     inc    cx
  484.     cmp    cx, 080h
  485.     jne    Xinit_gfx4
  486.     mov    cx, 180h
  487.     xor    al, al
  488. Xinit_gfx5:
  489.     out    dx, al
  490.     dec    cx
  491.     jnz    Xinit_gfx5
  492.     jne    Xinit_gfx4
  493.     ret
  494.  
  495. ; Xinitialize the sin-lookup-table
  496. ; used registers: all ?
  497.  
  498. Xinit_sin:
  499.     xor    ax, ax
  500.     mov    cx, Xsin_values+1
  501.     xor    di, di
  502. Xinit_sin1:
  503.     push    ax
  504.     push    cx
  505.     push    di
  506.     call    Xsin
  507.     mov    ds:Xsins[di], ax
  508.     mov    ds:Xsins3[di], ax
  509.     neg    di
  510.     mov    ds:Xsins2[di], ax
  511.     neg    ax
  512.     mov    ds:Xsins3[di], ax
  513.     neg    di
  514.     mov    ds:Xsins2[di], ax
  515.     pop    di
  516.     pop    cx
  517.     pop    ax
  518.     inc    ax
  519.     inc    di
  520.     inc    di
  521.     dec    cx
  522.     jnz    Xinit_sin1
  523.     xor    ebx, ebx
  524.     ret
  525.  
  526. ; check if a key was pressed
  527. ; used registers: ax
  528.  
  529. Xkey_pressed:
  530.     mov    ah, 01h
  531.     int    16h
  532.     ret
  533.  
  534. Xmain:
  535.     call    Xinit
  536. Xmain_loop:
  537.     cmp    Xtimer, 1400
  538.     jz    Xmain_end
  539.     call    Xproceed
  540.     call    Xbuild
  541.     call    Xdump
  542.     call    Xkey_pressed
  543.     jz    Xmain_loop
  544.     mov    ah, 00h
  545.     int    16h
  546. Xmain_end:
  547.     call    Xclean_up
  548.     mov    ax, 4c00h
  549.     int    21h
  550.  
  551. ; create the mul-lookup-table
  552. ; used registers: all ?
  553.  
  554. Xinit_fastmul:
  555.     push    es
  556.     mov    ax, seg _fastmul
  557.     mov    es, ax
  558.     xor    ebx, ebx
  559. Xinit_fastmul1:
  560.     mov    al, bh
  561.     imul    bl
  562.     sar    ax, 7
  563.     mov    es:[bx], al
  564.     inc    bx
  565.     jnz    Xinit_fastmul1
  566.     pop    es
  567.     ret
  568.  
  569. ; move the sun-source
  570. ; used registers: all ?
  571.  
  572. Xproceed:
  573.     add    Xtimer, 1
  574.     mov    bx, Xtimer        ; move the light-source
  575.     add    bx, 6000
  576.     and    bx, (8*Xsin_values)-2
  577.     mov    ax, Xsins[bx]
  578.     sar    ax, 8
  579.     neg    al
  580.     mov    Xsun_y, al
  581.     mov    cx, Xcoss[bx]
  582.     mov    bx, Xtimer
  583.     shl    bx, 2
  584.     add    bx, Xtimer
  585.     add    bx, 588h
  586.     and    bx, (4*Xsin_values)-1
  587.     add    bx, bx
  588.     mov    ax, Xsins[bx]
  589.     imul    cx
  590.     sar    dx, 8
  591.     or    dl, dl
  592.     jns    Xproceed1
  593.     neg    dl
  594. Xproceed1:
  595.     mov    Xsun_x, dl
  596.     mov    ax, Xcoss[bx]
  597.     imul    cx
  598.     sar    dx, 8
  599.     mov    Xsun_z, dl
  600.  
  601.     mov    ax, Xtimer        ; rotate the world
  602.     add    ax, ax
  603.     add    ax, 120h
  604.     mov    bx, ax
  605.     and    bx, 8*Xsin_values-2
  606.     mov    ax, Xsins[bx]
  607.     add    ah, 80h
  608.     shr    ax, 6
  609.     add    ax, ax
  610.     mov    bx, ax
  611.  
  612.     shr    ax, Xsin_base
  613.     and    ax, 3
  614.     mov    Xphase, ax
  615.     and    bx, (Xsin_values)-1
  616.     add    bx, Xsin_values/2
  617.     add    bx, bx
  618.     mov    cx, 4
  619.     mov    si, offset Xpoint0
  620.     mov    di, offset Xx0
  621. Xproceed2:
  622.     mov    ax, ds:[si]        ; new x-coordinate
  623.     imul    Xcoss[bx]
  624.     mov    bp, dx
  625.     mov    ax, ds:[si+2]
  626.     imul    Xsins[bx]
  627.     sub    bp, dx
  628.     add    bp, bp
  629.     mov    ds:[di], bp
  630.  
  631.     mov    ax, ds:[si]        ; new y-coordinate
  632.     imul    Xsins[bx]
  633.     mov    bp, dx
  634.     mov    ax, ds:[si+2]
  635.     imul    Xcoss[bx]
  636.     add    bp, dx
  637.     sar    bp, 1
  638.     mov    ds:[di+8], bp
  639.     add    si, 4
  640.     add    di, 2
  641.     dec    cx
  642.     jnz    Xproceed2
  643.  
  644.     test    Xtimer, 1
  645.     je    Xproceed3
  646.     mov    di, offset Xhght1
  647.     call    Xmake_fractal
  648.     mov    bx, Xtimer
  649.     shl    bx, 9
  650.     mov    di, offset Xhght1
  651.     call    Xget_normals
  652.     jmp    Xproceed4
  653. Xproceed3:
  654.     mov    di, offset Xhght2
  655.     call    Xmake_fractal
  656.     mov    bx, Xtimer
  657.     shl    bx, 9
  658.     mov    di, offset Xhght2
  659.     call    Xget_normals
  660. Xproceed4:
  661.     cmp    Xtimer,1
  662.     jne    Xproceed5
  663.     mov    cx, 80h
  664.     xor    eax, eax
  665.     mov    di, 200h
  666.     rep    stosd
  667. Xproceed5:
  668.     add    Xoffset, 200h
  669.     ret
  670.  
  671. ; pseudo random number generator
  672. ; used registers: ax, dx
  673.  
  674. Xrand:
  675.     mov    ax, 1549h
  676.     mul    Xsrand
  677.     xor    ax, 4286h
  678.     mov    Xsrand, ax
  679.     ret
  680.  
  681. ; create landscape "sink"
  682. ; used registers: eax, ebx, ecx, edx, edi
  683.  
  684. Xsink:
  685.     xor    di, di
  686.     mov    cx, 0080h
  687. Xsink1:
  688.     mov    bx, 0080h
  689. Xsink2:
  690.     mov    al, 40h
  691.     sub    al, bl
  692.     imul    al
  693.     mov    dx, ax
  694.     mov    al, 40h
  695.     sub    al, cl
  696.     imul    al
  697.     add    ax, dx
  698.     shl    eax, 16
  699.     push    bx
  700.     push    cx
  701.     push    di
  702.     call    Xsqrt
  703.     pop    di
  704.     pop    cx
  705.     pop    bx
  706.     mul    ax
  707.     shl    dx, 1
  708.     sub    dx, 2800h
  709.     mov    es:[di], dx
  710.     add    di, 4
  711.     dec    bx
  712.     jnz    Xsink2
  713.     dec    cx
  714.     jnz    Xsink1
  715.     ret
  716.  
  717. ; calculate the a sin-value ax -> ax
  718. ; used registers: all ?
  719.  
  720. Xsin:
  721.     mov    ebx, 3373259426 ; <-- 2**30 * pi
  722.     movzx    eax, ax        ; calculate x
  723.     mul    ebx
  724.     shrd    eax, edx, Xsin_base+1
  725.     mov    esi, eax    ; iteratively calculate the summands
  726.     mov    ebp, eax    ; +x
  727.     mov    ebx, 6/2    ; -x^3 / 3!
  728.     call    Xtaylor
  729.     sub    ebp, eax
  730.     mov    bl, 20/2    ; +x^5 / 5!
  731.     call    Xtaylor
  732.     add    ebp, eax
  733.     mov    bl, 42/2    ; -x^7 / 7!
  734.     call    Xtaylor
  735.     sub    ebp, eax
  736.     mov    bl, 72/2    ; +x^9 / 9!
  737.     call    Xtaylor
  738.     add    ebp, eax
  739.     mov    bl, 110/2    ; -x^11 / 11!
  740.     call    Xtaylor
  741.     sub    ebp, eax
  742.     mov    bl, 156/2    ; +x^13 / 13!
  743.     call    Xtaylor
  744.     add    ebp, eax
  745.     mov    bl, 210/2/2    ; -x^15 / 15! , avoid 0x40000000
  746.     call    Xtaylor
  747.     sub    ebp, eax
  748.     shr    ebp, 15
  749.     mov    eax, ebp
  750.     ret
  751.  
  752. ; calculate the square-root: eax -> eax
  753. ; used registers: eax, ebx, ecx, edx, edi
  754.  
  755. Xsqrt:
  756.     mov    edx, eax
  757.     mov    ebx, 80000000h
  758. Xsqrt_1:
  759.     rol    ebx, 1
  760.     shr    edx, 2
  761.     jnz    Xsqrt_1
  762.     xor    edi, edi
  763.     mov    ecx, eax
  764. Xsqrt_2:
  765.     or    ebx, ebx
  766.     jz    Xsqrt_4
  767.     add    edi, ebx
  768.     mov    eax, edi
  769.     mul    edi
  770.     cmp    ecx, eax
  771.     ja    Xsqrt_3
  772.     sub    edi, ebx
  773. Xsqrt_3:
  774.     shr    ebx, 1
  775.     jmp    Xsqrt_2
  776. Xsqrt_4:
  777.     mov    eax, edi
  778.     ret
  779.  
  780. ; auxiliary routine to get the next summand in the Xtaylor-series of sin
  781. ; used registers: ?
  782.  
  783. Xtaylor:
  784.     mul    esi
  785.     shrd    eax, edx, 30
  786.     mul    esi
  787.     shrd    eax, edx, 31
  788.     xor    edx, edx
  789.     div    ebx
  790.     ret
  791.  
  792. _sun     ends
  793.     end Xmain
  794.