home *** CD-ROM | disk | FTP | other *** search
/ The Party 1994: Try This At Home / disk_image.bin / source / spam / spam.asm < prev    next >
Assembly Source File  |  1994-09-30  |  33KB  |  1,611 lines

  1.         .MODEL COMPACT
  2.         PAGE 65535, 132
  3.  
  4. STACK        100h            ; stack-size
  5.  
  6. HUGE        =    16384        ; used in ray-part
  7. ROWS        =    120        ; screen-height
  8. COLUMNS        =    160        ; screen-width
  9. ZOOM_SIZE    =    0100h        ; border-length of zoom-data
  10. SIN_BASE    =    11        ; dual-logarithm of sin_size
  11. SIN_SIZE    =    1 SHL SIN_BASE    ; sin-values in [0;pi/2[
  12. CBOXCOLOR    =    9        ; additional colors for rays
  13. CPLANE        =    3        ; planes for ray
  14.  
  15. _DATA        SEGMENT PUBLIC 'DATA'
  16.                     ; initialized data
  17.                       ; general
  18. Timer        DW    0            ; timer -- clock of the intro
  19. Rand        DW    69            ; random number store
  20. RandMax        DW    16            ; random-amplitude
  21. aCRT        DW    00e11h        ; most crt-registers must be
  22.         DW    00d06h
  23.         DW    03e07h
  24.         DW    0c109h
  25.         DW    0ea10h
  26.         DW    0df12h
  27.         DW    04013h
  28.         DW    0e715h
  29.         DW    00616h
  30. CCRT        = (OFFSET $ - OFFSET ACRT) / 2
  31.  
  32.                       ; ray-part
  33. include        ray.inc             ; data for ray-positions
  34. aBoxColor    DB    004h, 004h, 01ch    ; blue
  35.         DB    03fh, 03fh, 004h    ; brite yellow
  36.         DB    004h, 03fh, 007h    ; green
  37.         DB    02fh, 02fh, 02fh    ; brite grey
  38.         DB    01fh, 01fh, 01fh    ; grey
  39.         DB    011h, 011h, 011h    ; dark grey
  40.         DB    037h, 033h, 004h    ; gold
  41.         DB    03fh, 004h, 004h    ; red
  42.         DB    000h, 000h, 000h    ; black
  43.  
  44. ;        box flying in the background
  45. RaPlane1    DW       0h,    0h,  100h ; left side
  46.         DW       0h,  200h,  100h
  47.         DW     200h,    0h,-0c00h
  48.         DB    3, 1
  49.         DW       0h,    0h, -100h ; right side
  50.         DW       0h,  200h,  100h
  51.         DW     200h,    0h,-0c00h
  52.         DB    5, 0
  53.         DW     200h,    0h,  100h ; front side
  54.         DW       0h,  200h,  100h
  55.         DW       0h,    0h,-0c00h
  56.         DB    4, 0
  57.  
  58. ;        german flag flying in the foreground
  59. RaPlane2    DW     300h,    0h,  100h ; black stripe
  60.         DW       0h,  0aah,  100h
  61.         DW       0h,    0h, -500h
  62.         DB     8, 0
  63.         DW     300h,    0h,  100h ; red stripe
  64.         DW       0h,  0aah,   55h
  65.         DW       0h,    0h, -500h
  66.         DB     7, 0
  67.         DW     300h,    0h,  100h ; gold stripe
  68.         DW       0h,  0aah,  -55h
  69.         DW       0h,    0h, -500h
  70.         DB     6, 0
  71.  
  72. ;        box flying from back-right to front-left
  73. RaPlane3    DW       0h,    0h, -100h ; right side
  74.         DW       0h,  200h,  100h
  75.         DW     200h,    0h,-0200h
  76.         DB    5, 0
  77.         DW     200h,    0h,  100h ; left side
  78.         DW       0h,  200h,  100h
  79.         DW       0h,    0h,-0200h
  80.         DB    4, 0
  81.         DW       0h,    0h,  100h ; front side
  82.         DW       0h,  200h,  100h
  83.         DW     200h,    0h,-0200h
  84.         DB    3, 1
  85.  
  86.                       ; zoom-part
  87. ZShrink        DW    0ffffh            ; zoom-quotient: ffff=min, 8000=max
  88. ZLevel        DW    20            ; count of zooms of the landscape
  89.                       ; voxel-part
  90. VAlpha        DW    OFFSET aSin        ; rotate-angle around x-axis
  91. VBeta        DW    OFFSET aSin+2*SIN_SIZE+4; rotate-angle around y-axis
  92. VaEdge        DW    -5555h,-5555h        ; coordinated of the edge-points
  93.         DW    -5555h, 5555h
  94.         DW     5555h, 5555h
  95.         DW     5555h,-5555h
  96. Waver        DW    0
  97.                     ; un-initialized data
  98.                       ; general
  99. qDummy        DD    ?            ; dummy, used in initialization
  100.                       ; ray-part
  101. RaNormal    DW    CPLANE*3 DUP (?) 
  102. RpNormal    DW    ?
  103. Rt        DW    ?
  104. RpaPlane    DW    ?
  105. RColor        DB    ?
  106. RBackground    DB    ?
  107. RcVisiblePlanes    DW    ?
  108. Rtemp        DW    ?
  109. Rc0        DW    ?
  110. Rc1        DW    ?
  111. Ry2        DW    ?
  112. Rx        DW    ?
  113. Ry        DW    ?
  114. Rr        DW    ?
  115. Rl1        DW    ?
  116. Rl2        DW    ?
  117. Rts        DW    8 DUP (?)
  118. Rte        DW    8 DUP (?)
  119. R_a04        DW    200h
  120. R_a24        DW    0h
  121. Ra00        DW    ?
  122. Ra01        DW    ?
  123. Ra02        DW    ?
  124. Ra03        DW    ?
  125. Ra04        DW    ?
  126. Ra10        DW    ?
  127. Ra11        DW    ?
  128. Ra12        DW    ?
  129. Ra13        DW    ?
  130. Ra14        DW    ?
  131. Ra20        DW    ?
  132. Ra21        DW    ?
  133. Ra22        DW    ?
  134. Ra23        DW    ?
  135. Ra24        DW    ?
  136.                       ; voxel-part
  137. Vx0        DW    ?            ; mapped coordinates of the
  138. Vy0        DW    ?            ; edge-points
  139. Vx1        DW    ?
  140. Vy1        DW    ?
  141. Vx2        DW    ?
  142. Vy2        DW    ?
  143. Vx3        DW    ?
  144. Vy3        DW    ?
  145. Vdx1        DW    ?            ; differentials for display
  146. Vdx2        DW    ?
  147. Vdx3        DW    ?
  148. Vdx        DW    ?
  149. Vddx        DW    ?
  150. Vdy1        DW    ?
  151. Vdy2        DW    ?
  152. Vdy3        DW    ?
  153. Vdy        DW    ?
  154. Vddy        DW    ?
  155. aSin        =    THIS WORD        ; sin-values
  156. aSin0        DW    2*SIN_SIZE DUP (?)  ; area: [0.0*pi; 1.0*pi[
  157. aSin1        DW    2*SIN_SIZE DUP (?)  ; area: [1.0*pi; 2.0*pi[
  158. aSin2        DW    1*SIN_SIZE+1 DUP (?); area: [2.0*pi; 3.0*pi]
  159. SIN2COS        =    2*SIN_SIZE
  160.  
  161. aaColor        DB    128*128 DUP (?)     ; colors of voxels
  162. aaLevel        DB    128*128 DUP (?)     ; heights of voxels
  163.  
  164. aLevel        DW    2*SIN_SIZE DUP (?)  ; heights in sin-sample
  165. _DATA        ENDS
  166.  
  167. _DATA2        SEGMENT PUBLIC 'BSS'    ; holds various stuff
  168.         DB    65535 DUP (?)
  169. _DATA2        ENDS
  170.  
  171. _DATA3        SEGMENT PUBLIC 'BSS'    ; holds various stuff
  172.         DB    65535 DUP (?)
  173. _DATA3        ENDS
  174.  
  175. INTRO_TEXT    SEGMENT PUBLIC 'CODE'
  176.         ASSUME    CS:INTRO_TEXT; DS:_DATA; ES:_DATA2
  177.  
  178. ; ============================================================================
  179. ;        Routines that are not part-specific
  180. ; ============================================================================
  181.         .286
  182.  
  183. ynSync    DB    0            ; boolean, indication new frame
  184. pTimerOld    =    THIS DWORD    ; pointer to system timer-handler
  185. offTimerOld    DW    ?
  186. segTimerOld    DW    ?
  187. Timer_Counter    DW    0        ; system-timer-handler on overflow!
  188.  
  189. BubbleSort    PROC
  190.         mov    cx, RcVisiblePlanes
  191. BS_Loop1:    dec    cx
  192.         jle    BS_End
  193.         push    si
  194.         push    cx
  195. BS_Loop2:    mov    ax, ds:[si]
  196.         cmp    ax, ds:[si+2]
  197.         jng    BS_NoSwap
  198.         xchg    ax, ds:[si+2]
  199.         mov    ds:[si], ax
  200. BS_NoSwap:    add    si, 2
  201.         dec    cx
  202.         jne    BS_Loop2
  203.         pop    cx
  204.         pop    si
  205.         dec    cx
  206.         jmp    BS_Loop1
  207. BS_End:        ret
  208. BubbleSort    ENDP
  209.  
  210. Delay        PROC NEAR
  211.         pushf
  212.         mov    cx, 70
  213. Delay_Loop:    call    Sync
  214.         loop    Delay_Loop
  215.         sub    ds:[Timer], 70
  216.         popf
  217.         ret
  218. Delay        ENDP
  219.  
  220. MDone        PROC NEAR        ; clear-up everything
  221.         mov    dx, 0043h    ; slow-down the system-clock to
  222.         mov    al, 34h        ; it's common speed - 18.2 Hz
  223.         out    dx, al
  224.         mov    dl, 40h
  225.         mov    al, 00h
  226.         out    dx, al
  227.         out    dx, al
  228.         mov    ax, 2508h    ; restore the old timer-interrupt
  229.         mov    dx, cs:[segTimerOld] ; handler
  230.         mov    ds, dx
  231.         mov    dx, cs:[offTimerOld]
  232.         int    21h
  233.         mov    ax, 0003h    ; switch back to text-mode
  234.         int    10h
  235.         mov    ah, 01h        ; clear keyboard-buffer
  236.         int    16h
  237.         jz    MDone_NoKey
  238.         mov    ah, 00h
  239.         int    16h
  240. MDone_NoKey:    mov    ax, 4c00h    ; quit the program
  241.         int    21h
  242. MDone        ENDP
  243.  
  244. MInit        PROC NEAR
  245.         ASSUME    DS:INTRO_TEXT
  246.         push    cs        ; set-up segments
  247.         pop    ds
  248.         cld
  249.         mov    ax, 3508h    ; store old timer-interrupt
  250.         int    21h
  251.         mov    ds:[offTimerOld], bx
  252.         mov    ds:[segTimerOld], es
  253.         mov    ah, 25h        ; redirect timer-interrupt
  254.         mov    dx, OFFSET TimerHandler
  255.         int    21h
  256.         mov    dx, 0043h    ; set new speed of timer
  257.         mov    al, 34h        ; to approx. 70 Hz
  258.         out    dx, al
  259.         mov    dl, 40h
  260.         mov    al, 95h
  261.         out    dx, al
  262.         mov    al, 42h
  263.         out    dx, al
  264.         ASSUME DS:_DATA
  265.         mov    ax, SEG _DATA
  266.         mov    ds, ax
  267.         mov    ax, 0013h    ; init standard mode13
  268.         int    10h
  269.         mov    dx, 03c4h
  270.         mov    dx, 03c2h
  271.         mov    al, 0e3h    ; increase y-resolution to 60%
  272.         out    dx, al
  273.         mov    dx, 03d4h
  274.         mov    si, OFFSET aCRT
  275.         mov    cx, CCRT
  276.         rep    outsw
  277.         mov    dx, 03c8h    ; adress DAC-controller
  278.         xor    ax, ax
  279.         out    dx, al
  280.         inc    dl
  281.         xor    bx, bx        ; fill the first 64 DAC-registers
  282.         mov    cx, 40h        ; with colors, ranging from black
  283. MInit_DAC1:    out    dx, al        ; to green
  284.         mov    al, bl
  285.         out    dx, al
  286.         mov    al, bh
  287.         out    dx, al
  288.         inc    bl
  289.         loop    MInit_DAC1
  290.         xor    bl, bl
  291.         mov    cx, 40h        ; fill the next 64 DAC-registers with
  292. MInit_DAC2:    out    dx, al        ; colors, ranging from black to blue
  293.         mov    al, bl
  294.         shr    al, 1
  295.         out    dx, al
  296.         mov    al, bl
  297.         out    dx, al
  298.         mov    al, bh
  299.         inc    bl
  300.         loop    MInit_DAC2
  301.         mov    si, OFFSET aBoxColor
  302.         mov    cx, CBOXCOLOR*3
  303.         rep    outsb
  304.         mov    ax, 0a000h
  305.         .386
  306.         mov    gs, ax
  307.         .286
  308.         ret
  309. MInit        ENDP
  310.  
  311. Main        PROC NEAR        ; start-point of intro
  312.         call    MInit        ; MInitialization
  313.         call    RRun        ; show the ray-part
  314.         call    ZInit        ; show the zoom-part
  315.         call    ZRun
  316.         call    VInit        ; show the voxel-part
  317.         call    VRun
  318.         jmp    MDone        ; clear-up everything
  319. Main        ENDP
  320.  
  321. Random        PROC NEAR        ; this is just a simple random
  322.         push    ax        ; number generator, that yields a
  323.         push    dx        ; random-number in bp, while leaving
  324.         mov    ax, ds:[rand]    ; all other registers unchanged
  325.         mov    dx, 4217h
  326.         imul    dx
  327.         xor    ax, 1974h
  328.         mov    ds:[rand], ax
  329.         mov    dx, RandMax
  330.         imul    dx
  331.         mov    bp, dx
  332.         pop    dx
  333.         pop    ax
  334.         ret
  335. Random        ENDP
  336.  
  337. Sqrt        PROC
  338.         mov    bx, ax
  339.         mov    dl, 40h
  340.         xor    cx, cx
  341. Sqrt_TryNext:    xor    cl, dl
  342.         mov    al, cl
  343.         mul    al
  344.         cmp    ax, bx
  345.         jle    Sqrt_TakeIt
  346.         xor    cl, dl
  347. Sqrt_TakeIt:    shr    dl, 1
  348.         jnz    Sqrt_TryNext
  349.         mov    si, cx
  350.         ret
  351. Sqrt        ENDP
  352.  
  353. Sync        PROC NEAR
  354.         cmp    cs:[ynSync], 0    ; wait for a new frame ...
  355.         je    Sync
  356.         mov    cs:[ynSync], 0    ; now it's an old frame
  357.         inc    ds:[Timer]    ; enhance timer
  358. Sync_End:    push    ax
  359.         mov    ah, 01h
  360.         int    16h
  361.         jz    Sync_Done
  362.         jmp    MDone
  363. Sync_Done:    pop    ax
  364.         ret
  365. Sync        ENDP
  366.  
  367. TimerHandler    PROC    FAR
  368.         mov    cs:[ynSync], 1    ; report a new frame
  369.         add    cs:[Timer_Counter], 4295h ; call the system-timer-
  370.         jc    Timer_UseOld    ; interrupt if it's time again
  371.         push    ax
  372.         mov    al, 20h        ; acknowledge the interrupt to
  373.         out    20h, al        ; the irq-controller
  374.         pop    ax
  375.         iret
  376. Timer_UseOld:    jmp    cs:[pTimerOld]    ; call system-timer-handler
  377. TimerHandler    ENDP
  378.  
  379. ; ============================================================================
  380. ;        routines for the ray-tracing-part
  381. ; ============================================================================
  382. RAnimate    PROC
  383.         call    Sync
  384.         mov    dx, Rt
  385.         push    ds
  386.         mov    bx, seg _DATA2
  387.         neg    bx
  388.         mov    WORD PTR cs:RAnimate_Poke, bx
  389.         neg    bx
  390.         xor    si, si
  391.         mov    dx, Rt
  392.         mov    bp, ROWS
  393. RAnimate_Loop1:    mov    cx, COLUMNS
  394. RAnimate_Loop2:    mov    ds, bx
  395.         cmp    [si], dx
  396.         jle    RAnimate_Move
  397. RAnimate_Next:    inc    bx
  398.         dec    cx
  399.         jne    RAnimate_Loop2
  400.         add    WORD PTR cs:[RAnimate_Poke], 256-COLUMNS
  401.         dec    bp
  402.         jne    RAnimate_Loop1
  403.         pop    ds
  404.         ret
  405.  
  406. RAnimate_Move:    mov    ax, [si]
  407.         and    al, 0fh
  408.         or    al, 80h
  409.         .386
  410.         mov    ah, al
  411.         push    bx
  412.         add    bx, 1234h
  413. RAnimate_Poke    =    $-2
  414.         add    bx, bx
  415.         mov    gs:[bx], ax
  416.         pop    bx
  417.         .286
  418. RAnimate_More:    mov    ax, [si+2]
  419.         mov    [si], ax
  420.         cmp    ax, 07fffh
  421.         je    RAnimate_Moved
  422.         add    si, 2
  423.         jmp    RAnimate_More
  424. RAnimate_Moved:    xor    si, si
  425.         jmp    RAnimate_Next
  426. RAnimate    ENDP
  427.  
  428. RFade1        PROC
  429.         mov    si, OFFSET aBoxColor
  430.         mov    cx, CBOXCOLOR*3
  431.         mov    dx, 03c8h
  432.         mov    al, 80h
  433.         out    dx, al
  434.         inc    dx
  435. RFade1_Loop1:    inc    BYTE PTR ds:[si]
  436.         lodsb
  437.         cmp    al, 3fh
  438.         jna    RFade1_Ok
  439.         mov    al, 3fh
  440. RFade1_Ok:    out    dx, al
  441.         loop    RFade1_Loop1
  442.         ret
  443. RFade1        ENDP
  444.  
  445. RFade2        PROC
  446.         mov    dx, 03c8h
  447.         mov    al, 25h
  448.         out    dx, al
  449.         inc    dx
  450.         mov    ax, 3fh
  451.         sub    ax, Timer
  452.         out    dx, al
  453.         mov    ah, al
  454.         cmp    al, 0e5h
  455.         jae    RFade2_Ok
  456.         mov    al, 0e5h
  457. RFade2_Ok:    out    dx, al
  458.         mov    al, ah
  459.         out    dx, al
  460.         mov    ax, Timer
  461.         sub    al, 40h
  462.         shr    al, 1
  463.         cmp    al, 10h
  464.         jae    RFade2_End
  465.         xor    ah, ah
  466.         mov    si, ax
  467.         mov    di, COLUMNS-1
  468.         sub    di, si
  469.         add    si, si
  470.         add    di, di
  471.         mov    cx, ROWS
  472. RFade2_Loop:    .386
  473.         mov    WORD PTR gs:[si], 0000h
  474.         mov    WORD PTR gs:[di], 0000h
  475.         add    si, 0200h
  476.         add    di, 0200h
  477.         .286
  478.         loop    RFade2_Loop
  479. RFade2_End:    ret
  480. RFade2        ENDP
  481.  
  482. RInit        PROC
  483.         mov    ax, SEG _DATA
  484.         mov    ds, ax
  485.         mov    es, ax
  486.         call    RNormalize
  487.         mov    ax, SEG _DATA2
  488.         .386
  489.         mov    fs, ax
  490.         .286
  491.         xor    di, di
  492.         mov    Ry, -ROWS/2
  493. RInit_NRow:    mov    Rx, -COLUMNS/2
  494. RInit_NColumn:    mov    RBackground, 0
  495.         mov    ax, Ry        ; get the "distance" r to the z-axis
  496.         imul    Ry
  497.         mov    cx, ax        ;  y^2
  498.         mov    ax, Rx
  499.         imul    Rx
  500.         add    ax, cx        ; +x^2
  501.         call    Sqrt        ; sqrt
  502.         mov    Rr, si
  503.         add    si, si
  504.         jne    RInit_NoMid
  505.         jmp    RInit_Cont    ; so we dont have /0 below
  506. RInit_NoMid:    add    si, OFFSET aDr
  507.         mov    bx, [si]    ; get the angle of the (fracted?) ray
  508.         mov    ax, bx        ; calculate the angle to y-z-plane
  509.         mov    dx, [si+OFFSET aZ - OFFSET aDr]
  510.         mov    Ry2, dx
  511.         imul    Rx
  512.         idiv    Rr
  513.         mov    Rc0, ax
  514.         mov    bp, ax
  515.         mov    ax, bx        ; calculate the angle to x-z-plane
  516.         imul    Ry
  517.         idiv    Rr
  518.         neg    ax        ; flip the ray in y-direction
  519.         mov    Rc1, ax        ; (coz 0;0 is at the TOP of the screen)
  520.         mov    bx, ax        ; if the ray descends very slow, it
  521.         cmp    bx, 16        ; won't intersect the checkered plane
  522.         jng    RInit_Cont
  523.         mov    dx, 2        ; 2/dy = l = units in z-direction till
  524.         xor    ax, ax        ; the ray intersects the plane
  525.         div    bx
  526.         mov    cx, ax
  527.         imul    bp        ; l*dx is the x-coordinate of the point
  528.         mov    ax, cx
  529.         add    si, OFFSET aZ-OFFSET aDr ; l+"z-coordinate of the point
  530.         add    ax, Ry2        ; where the ray crosses the z-axis"
  531.         sar    ax, 8        ; is the z-coordinate
  532.         cmp    dx, 13        ; x < 13  - the borders of the plane
  533.         jge    RInit_Cont
  534.         cmp    dx, -13        ; x > -13
  535.         jl    RInit_Cont
  536.         cmp    ax, 22        ; z < 22
  537.         jge    RInit_Cont
  538.         cmp    ax, -2        ; z > -2
  539.         jl    RInit_Cont
  540.         shr    ax, 1        ; make checkers 2*x units large
  541.         shr    dx, 1
  542.         adc    ax, dx
  543.         and    al, 1        ; 1/0 is the color here
  544.         inc    al
  545.         mov    RBackground, al
  546.  
  547. RInit_Cont:    mov    ds:[Rtemp], di
  548.         mov    ds:[RpNormal], OFFSET RaNormal
  549.         mov    bp, OFFSET Rts
  550.         mov    RcVisiblePlanes, 0
  551.         mov    si, RpaPlane     ; Fill in the plane-coordinates
  552.         mov    cx, CPLANE
  553. RInit_NextWall:    push    cx
  554.         mov    di, ds:[RpNormal]; check with the common scalar-
  555.         mov    ax, ds:[Rc0]     ; product if the wall is visible
  556.         imul    WORD PTR ds:[di] ; at all
  557.         mov    cl, ah
  558.         mov    ch, dl
  559.         mov    ax, ds:[Rc1]
  560.         imul    WORD PTR ds:[di+2]
  561.         add    cl, ah
  562.         adc    ch, dl
  563.         add    cx, ds:[di+4]
  564.         sub    cx, 10h        ; be a little bit conservative
  565.         cmp    cx, 0
  566.         jns    RInit_Section
  567.         add    si, 20
  568.         jmp    RInit_NoSect
  569. RInit_Section:    mov    di, OFFSET Ra00    ; into the equations for the
  570.         mov    cx, 3        ; intersection-algorithm
  571. RInit_FillIn:    movsw
  572.         movsw
  573.         add    di, 2
  574.         movsw
  575.         add    di, 2
  576.         dec    cx
  577.         jne    RInit_FillIn
  578.         lodsw
  579.         mov    RColor, al
  580.         push    si
  581.         call    RSec
  582.         pop    si
  583.         cmp    ax, bx
  584.         jg    RInit_NoSect
  585.         shl    ax, 4
  586.         shl    bx, 4
  587.         or    al, RColor
  588.         or    bl, RColor
  589.         mov    ds:[bp], ax
  590.         mov    ds:[bp+OFFSET Rte-OFFSET Rts], bx
  591.         inc    RcVisiblePlanes
  592.         add    bp, 2
  593. RInit_NoSect:    pop    cx
  594.         add    ds:[RpNormal], 6
  595.         dec    cx
  596.         jne    RInit_NextWall
  597.         mov    si, OFFSET Rts
  598.         call    BubbleSort
  599.         mov    si, OFFSET Rte
  600.         call    BubbleSort
  601.         call    RPack
  602.         .386
  603.         mov    ax, fs
  604.         inc    ax
  605.         mov    fs, ax
  606.         .286
  607.         mov    di, ds:[Rtemp]
  608.         mov    al, RBackground
  609.         or    al, 80h
  610.         .386
  611.         mov    ah, al
  612.         mov    gs:[di], ax
  613.         add    di, 2
  614.         .286
  615.         inc    Rx
  616.         cmp    Rx, COLUMNS/2
  617.         je    RInit_NextR
  618.         jmp    RInit_NColumn
  619. RInit_NextR:    
  620.  
  621.         add    di, 2*(256-COLUMNS)
  622.         inc    Ry
  623.         cmp    Ry, ROWS/2
  624.         je    RInit_Done
  625.         jmp    RInit_NRow
  626. RInit_Done:    ret
  627. RInit        ENDP
  628.  
  629. RNormalize    PROC
  630.         mov    si, RpaPlane    ; RInitialize normal-vectors
  631.         mov    di, OFFSET RaNormal
  632.         mov    cx, CPLANE
  633. RNormalize_Loop:mov    ax, ds:[si+6]    ; x2*y3
  634.         imul    WORD PTR ds:[si+14]
  635.         mov    bl, ah
  636.         mov    bh, dl
  637.          mov    ax, ds:[si+12]    ; -x3*y2
  638.         imul    WORD PTR ds:[si+8]
  639.         sub    bl, ah
  640.         sbb    bh, dl
  641.         mov    ds:[di], bx    ; = z1
  642.         mov    ax, ds:[si+12]    ; x3*y1
  643.         imul    WORD PTR ds:[si+2]
  644.         mov    bl, ah
  645.         mov    bh, dl
  646.         mov    ax, ds:[si]    ; -x1*y3
  647.         imul    WORD PTR ds:[si+14]
  648.         sub    bl, ah
  649.         sbb    bh, dl
  650.         mov    ds:[di+2], bx    ; = z2
  651.         mov    ax, ds:[si]    ; x1*y2
  652.         imul    WORD PTR ds:[si+8]
  653.         mov    bl, ah
  654.         mov    bh, dl
  655.         mov    ax, ds:[si+6]    ; -x2*y1
  656.         imul    WORD PTR ds:[si+2]
  657.         sub    bl, ah
  658.         sbb    bh, dl
  659.         mov    ds:[di+4], bx    ; = z3
  660.         cmp    BYTE PTR ds:[si+19], 0
  661.         je    RNormalize_Ok
  662.         neg    WORD PTR ds:[di]
  663.         neg    WORD PTR ds:[di+2]
  664.         neg    WORD PTR ds:[di+4]
  665. RNormalize_Ok:    add    si, 20
  666.         add    di, 6
  667.         loop    RNormalize_Loop
  668.         ret
  669. RNormalize    ENDP
  670.  
  671. RPack        PROC
  672.         xor    di, di
  673.         mov    cx, RcVisiblePlanes
  674.         or    cx, cx
  675.         je    RPack_Void
  676.         mov    si, OFFSET Rts
  677. RPack_Loop:    lodsw
  678.         .386
  679.         mov    fs:[di], ax
  680.         .286
  681.         add    di, 2
  682.         dec    cx
  683.         jne    RPack_Loop
  684.         mov    ax, ds:[si+OFFSET Rte-OFFSET Rts-2]
  685.         and    al, 0f0h
  686.         or    al, RBackground
  687.         .386
  688.         mov    fs:[di], ax
  689.         .386
  690.         add    di, 2
  691. RPack_Void:    .386
  692.         mov    WORD PTR fs:[di], 07fffh
  693.         .286
  694.         ret
  695. RPack        ENDP
  696.  
  697. RRun        PROC
  698.         cmp    Timer, 0    ; first animation-part
  699.         jne    RRun_1b
  700.         mov    Rt, -4000h
  701.         mov    RpaPlane, OFFSET RaPlane1
  702.         mov    R_a04, 400h
  703.         mov    R_a24, 0
  704.         call    RInit
  705. RRun_1b:    cmp    Timer, 100h
  706.         jae    RRun_2
  707.         add    Rt, 084h
  708.         call    RAnimate
  709.         jmp    RRun_End
  710. RRun_2:        cmp    Timer, 100h
  711.         jne    RRun_2b
  712.         mov    Rt, -4200h
  713.         mov    RpaPlane, OFFSET RaPlane2
  714.         mov    R_a04, 200h
  715.         mov    R_a24, 0h
  716.         call    RInit
  717. RRun_2b:    cmp    Timer, 200h
  718.         jae    RRun_3
  719.         add    Rt, 100h
  720.         call    RAnimate
  721.         jmp    RRun_End
  722. RRun_3:        cmp    Timer, 200h
  723.         jne    RRun_3b
  724.         mov    Rt, -2000h
  725.         mov    RpaPlane, OFFSET RaPlane3
  726.         mov    R_a04, -400h
  727.         mov    R_a24,  300h
  728.         call    RInit
  729. RRun_3b:    cmp    Timer, 300h
  730.         jae    RRun_4
  731.         add    Rt, 080h
  732.         call    RAnimate
  733.         jmp    RRun_End
  734. RRun_4:        cmp    Timer, 340h
  735.         jae    RRun_4b
  736.         call    RFade1
  737.         call    Sync
  738.         jmp    RRun_End
  739. RRun_4b:    cmp    Timer, 340h
  740.         jne    RRun_5
  741.         call    RFade2
  742.         call    RWhite
  743. RRun_5:        cmp    Timer, 380h
  744.         jae    RRun_End
  745.         call    RFade2
  746.         call    Sync
  747. RRun_End:    cmp    Timer, 380h
  748.         .386
  749.         jl    RRun
  750.         .286
  751.         ret
  752. RRun        ENDP
  753.  
  754. RSec        PROC
  755.         mov    ax, Rc0        ; fill in the variables for c
  756.         neg    ax
  757.         mov    Ra02, ax
  758.         mov    ax, Rc1
  759.         neg    ax
  760.         mov    Ra12, ax
  761.         mov    Ra22, -100h
  762.         mov    ax, Ry2        ; fill in the variables for y
  763.         add    Ra23, ax
  764.         mov    ax, R_a04    ; fill in the "time" vector
  765.         mov    Ra04, ax
  766.         mov    ax, R_a24
  767.         mov    Ra24, ax
  768.         mov    Ra14, 0
  769.  
  770.         mov    cx, 2
  771.         mov    si, OFFSET Ra00
  772. RSec_LoopI:    mov    bx, 0
  773. RSec_LoopJ:    cmp    bx, 4
  774.         je    RSec_Skip1
  775.         mov    ax, ds:[OFFSET Ra20+bx]
  776.         imul    WORD PTR ds:[si+4]
  777.         mov    dh, dl
  778.         mov    dl, ah
  779.         add    ds:[si+bx], dx
  780. RSec_Skip1:    add    bx, 2
  781.         cmp    bx, 10
  782.         jne    RSec_LoopJ
  783.         add    si, 10
  784.         dec    cx
  785.         jne    RSec_LoopI
  786.  
  787. ;    *  *  0  *  *
  788. ;    *  *  0  *  *
  789. ;    *  * -1  *  *
  790.  
  791.         cmp    Ra01, 0
  792.         je    RSec_Idle1
  793.  
  794.         cmp    Ra11, 0
  795.         jne    RSec_Mark1
  796.         mov    ax, Ra00
  797.         xchg    ax, Ra10
  798.         mov    Ra00, ax
  799.         mov    ax, Ra01
  800.         xchg    ax, Ra11
  801.         mov    Ra01, ax
  802.         mov    ax, Ra03
  803.         xchg    ax, Ra13
  804.         mov    Ra03, ax
  805.         mov    ax, Ra04
  806.         xchg    ax, Ra14
  807.         mov    Ra04, ax
  808.         jmp    RSec_Idle1
  809.  
  810. RSec_Mark1:    mov    cx, 5
  811.         mov    si, OFFSET Ra00
  812. RSec_Loop3:    cmp    cx, 4
  813.         je    RSec_Skip2
  814.         cmp    cx, 3
  815.         je    RSec_Skip2
  816.         mov    ax, ds:[si]
  817.         imul    Ra11
  818.         mov    bh, dl
  819.         mov    bl, ah
  820.         mov    ax, ds:[si+10]
  821.         imul    Ra01
  822.         sub    bl, ah
  823.         sbb    bh, dl
  824.         mov    ds:[si], bx
  825. RSec_Skip2:    add    si, 2
  826.         dec    cx
  827.         jne    RSec_Loop3
  828.         mov    Ra01, 0
  829.  
  830. ;    *  0  0  *  *
  831. ;    *  *  0  *  *
  832. ;    *  * -1  *  *
  833.  
  834. RSec_Idle1:    cmp    Ra00, 0
  835.         je    RSec_Short1
  836.         mov    si, OFFSET Ra01
  837.         mov    cx, 4
  838. RSec_Loop4:    cmp    cx, 3
  839.         je    RSec_Skip3
  840.         mov    ax, ds:[si+10]
  841.         imul    Ra00
  842.         mov    bh, dl
  843.         mov    bl, ah
  844.         mov    ax, ds:[si]
  845.         imul    Ra10
  846.         sub    bl, ah
  847.         sbb    bh, dl
  848.         mov    ds:[si+10], bx
  849. RSec_Skip3:    add    si, 2
  850.         dec    cx
  851.         jne    RSec_Loop4
  852.  
  853. ;    *  0  0  *  *
  854. ;    0  *  0  *  *
  855. ;    *  * -1  *  *
  856.  
  857. RSec_Short1:    cmp    Ra04, 0
  858.         jne    RSec_NoZero1
  859.         mov    ax, Ra03
  860.         mov    dx, Ra00
  861.         or    ax, ax
  862.         jns    RSec_NoSign1
  863.         neg    ax
  864.         neg    dx
  865. RSec_NoSign1:    or    dx, dx
  866.         js    RSec_JumpX
  867.         cmp    dx, ax
  868.         jl    RSec_JumpX
  869.         mov    Rl1, -HUGE
  870.         mov    Rl2,  HUGE
  871.         jmp    RSec_Done1
  872. RSec_JumpX:    jmp    RSec_NoSection
  873.  
  874. RSec_NoZero1:    mov    ax, Ra03
  875.         mov    dx, -100h
  876.         imul    dx
  877.         idiv    Ra04
  878.         mov    bx, ax
  879.         mov    ax, Ra00
  880.         sub    ax, Ra03
  881.         mov    dx, 100h
  882.         imul    dx
  883.         idiv    Ra04
  884.         cmp    bx, ax
  885.         jg    RSec_NoSwap1
  886.         xchg    bx, ax
  887. RSec_NoSwap1:    mov    Rl1, ax
  888.         mov    Rl2, bx
  889.  
  890. RSec_Done1:    cmp    Ra14, 0
  891.         jne    RSec_NoZero2
  892.         mov    ax, Ra13
  893.         mov    dx, Ra11
  894.         or    ax, ax
  895.         jns    RSec_NoSign2
  896.         neg    ax
  897.         neg    dx
  898. RSec_NoSign2:    or    dx, dx
  899.         js    RSec_NoSection
  900.         cmp    dx, ax
  901.         jl    RSec_NoSection
  902.         mov    ax, -HUGE
  903.         mov    bx,  HUGE
  904.         jmp    RSec_Done2
  905. RSec_NoZero2:    mov    ax, Ra13
  906.         mov    dx, -100h
  907.         imul    dx
  908.         idiv    Ra14
  909.         mov    bx, ax
  910.         mov    ax, Ra11
  911.         sub    ax, Ra13
  912.         mov    dx, 100h
  913.         imul    dx
  914.         idiv    Ra14
  915.         cmp    bx, ax
  916.         jg    RSec_Done2
  917.         xchg    bx, ax
  918.  
  919. RSec_Done2:    cmp    ax, Rl1
  920.         jg    RSec_NoChange1
  921.         mov    ax, Rl1
  922. RSec_NoChange1:    cmp    bx, Rl2
  923.         jl    RSec_NoChange2
  924.         mov    bx, Rl2
  925. RSec_NoChange2:    ret
  926. RSec_NoSection:    xor    ax, ax
  927.         xor    bx, bx
  928.         dec    bx
  929.         ret
  930. RSec        ENDP
  931.  
  932. RWhite        PROC
  933.         push    es
  934.         .386
  935.         push    gs
  936.         .286
  937.         pop    es
  938.         mov    ax, 2525h
  939.         xor    di, di
  940.         mov    cx, 256*ROWS
  941.         rep    stosw
  942.         pop    es
  943.         ret
  944. RWhite        ENDP
  945.  
  946. ; ============================================================================
  947. ;        routines for the zoom-part
  948. ; ============================================================================
  949.         yZoom    DW    0
  950.  
  951. ZInit        PROC NEAR
  952.         xor    al, al
  953.         mov    dx, SEG _DATA3    ; Initialize height with 40h
  954.         mov    es, dx        ; use fs as the "new" buffer segment
  955.         xor    di, di
  956.         mov    ax, 2525h
  957.         mov    cx, 8000h
  958.         rep    stosw
  959.         .386
  960.         mov    ax, SEG _DATA2    ; use es as the "old" buffer segment
  961.         mov    fs, ax
  962.         mov    Timer, 0
  963.         ret
  964. ZInit        ENDP
  965.  
  966. ZRun        PROC NEAR
  967. ZRun_Start:    mov    ds:[ZShrink], 0ffffh ; reset the zoom-factor each stage
  968.         xor    ah, ah
  969.         mov    cx, ZOOM_SIZE/2    ; Zoom old _DATA2 into the new _DATA2;
  970.         mov    si, ZOOM_SIZE/4*(ZOOM_SIZE+1) ; the inner quarter is
  971.         xor    di, di        ; magnified to whold size, so that only
  972. ZRun_Zoom2:    push    cx        ; the wholes have to be filled
  973.         mov    cx, ZOOM_SIZE/2
  974. ZRun_Zoom1:    push    cx
  975.         mov    al, es:[si+ZOOM_SIZE+1] ; get the heights of four
  976.         cbw            ; points that build a square
  977.         mov    dx, ax
  978.         mov    al, es:[si+ZOOM_SIZE]
  979.         cbw
  980.         mov    cx, ax
  981.         mov    al, es:[si+1]
  982.         cbw
  983.         mov    bx, ax
  984.         mov    al, es:[si]
  985.         cbw
  986.         mov    fs:[di], al    ; just copy the point at the top-left
  987.         push    bx        ; interpolate and randomly displace
  988.         add    bx, ax        ; the point at the top-middle
  989.         sar    bx, 1
  990.         call    Random
  991.         add    bx, bp
  992.         mov    fs:[di+1], bl
  993.         add    cx, ax        ; interpolate and randomly displace
  994.         push    cx        ; the point at the left-middle
  995.         sar    cx, 1
  996.         call    Random
  997.         add    cx, bp
  998.         mov    fs:[di+ZOOM_SIZE], cl
  999.         pop    cx        ; interpolate and randomly displace
  1000.         pop    bx        ; the point at the center
  1001.         add    dx, bx
  1002.         add    dx, cx
  1003.         sar    dx, 2
  1004.         call    Random
  1005.         add    dx, bp
  1006.         mov    fs:[di+ZOOM_SIZE+1], dl
  1007.         inc    si        ; move to next column
  1008.         add    di, 2
  1009.         pop    cx
  1010.         dec    cx
  1011.         jne    ZRun_Zoom1    ; loop to next column
  1012.         add    si, ZOOM_SIZE/2 ; move pointers to next row
  1013.         add    di, ZOOM_SIZE
  1014.         pop    cx        ; check if it's time to refresh
  1015.         push    cx        ; the display
  1016.         test    cx, 3
  1017.         jne    ZRun_NoRefresh
  1018.         push    si
  1019.         push    di
  1020.         call    ZShow        ; draw the next picture
  1021.         mov    ax, ds:[ZShrink]; recalculate the zoom-factor
  1022.         mov    dx, 64136
  1023.         mul    dx
  1024.         mov    ds:[ZShrink], dx
  1025.         pop    di
  1026.         pop    si
  1027. ZRun_NoRefresh:    pop    cx        ; loop to next row
  1028.         dec    cx
  1029.         jne    ZRun_Zoom2
  1030.         call    Random        ; avoid cycles in randomness
  1031.         cmp    ds:[ZLevel], 6
  1032.         ja    ZRun_ItsOK
  1033.         sub    ds:[RandMax], 3 ; fractal-dimension <2.5 ...
  1034. ZRun_ItsOK:    mov    ds:[ZShrink], 0ffffh ; reset the zoom-factor each stage
  1035.         mov    ax, es        ; swap between display- and calculation
  1036.         mov    dx, fs        ; _DATA2
  1037.         xchg    ax, dx
  1038.         mov    es, ax
  1039.         mov    fs, dx
  1040.         dec    ds:[ZLevel]    ; do a few loops 
  1041.         jne    ZRun_Start
  1042.         mov    ax, 1409
  1043. ZRun_Slow:    push    ax
  1044.         call    ZShow
  1045.         pop    ax
  1046.         sub    ds:[ZShrink], ax
  1047.         sub    ax, 31
  1048.         jnc    ZRun_Slow
  1049.         mov    ds:[ZShrink], 8000h
  1050. ZRun        ENDP
  1051.  
  1052. ZShow        PROC NEAR
  1053.         call    Sync
  1054. ZShow_NoExpand:    mov    ax, ds:[ZShrink]
  1055.         push    ax
  1056.         neg    ax
  1057.         push    ax
  1058.         mov    dx, ZOOM_SIZE/2
  1059.         mul    dx
  1060.         add    ax, 8000h
  1061.         adc    dx, 0000h
  1062.         mov    cs:[yZoom], ax
  1063.         mov    ax, ZOOM_SIZE
  1064.         mul    dx
  1065.         mov    si, ax
  1066.         pop    ax
  1067.         mov    dx, ZOOM_SIZE/2
  1068.         mul    dx
  1069.         add    ax, 8000h
  1070.         adc    dx, 0000h
  1071.         mov    bp, ax
  1072.         add    si, dx
  1073.         pop    dx
  1074.         add    dx, dx
  1075.         push    ds
  1076.         mov    di, (ROWS-ZOOM_SIZE/2) SHL 8 + (COLUMNS-ZOOM_SIZE/2)
  1077.         mov    cx, ZOOM_SIZE/2
  1078.         push    es
  1079.         pop    ds
  1080. ZShow_Loop2:    push    cx
  1081.         push    si
  1082.         mov    bx, bp
  1083.         mov    cx, ZOOM_SIZE/4
  1084. ZShow_Loop1:    mov    al, ds:[si]
  1085.         add    bx, dx
  1086.         adc    si, 1
  1087.         mov    ah, al
  1088.         mov    gs:[di], ax
  1089.         add    di, 2
  1090.         mov    al, ds:[si]
  1091.         mov    ah, al
  1092.         mov    gs:[di], ax
  1093.         add    bx, dx
  1094.         adc    si, 1
  1095.         add    di, 2
  1096.         dec    cx
  1097.         jne    ZShow_Loop1
  1098.         pop    si
  1099.         add    cs:[yZoom], dx
  1100.         jnc    ZShow_NoSkip
  1101.         add    si, ZOOM_SIZE
  1102. ZShow_NoSkip:    add    si, ZOOM_SIZE
  1103.         add    di, 512-ZOOM_SIZE
  1104.         xor    bx, bx
  1105.         pop    cx
  1106.         dec    cx
  1107.         jne    ZShow_Loop2
  1108.         pop    ds
  1109.         ret
  1110. ZShow        ENDP
  1111.  
  1112. ; ============================================================================
  1113. ;        routines for the voxel-part
  1114. ; ============================================================================
  1115. VAdvance    PROC NEAR
  1116.         cmp    ds:[Timer], 080h
  1117.         jne    VAdvance_0b
  1118.         call    Delay
  1119. VAdvance_0b:    jae    VAdvance_1
  1120.         add    ds:[VAlpha], 18h
  1121.         sub    ds:[VaEdge+00h], 0018h
  1122.         sub    ds:[VaEdge+02h], 0018h
  1123.         sub    ds:[VaEdge+04h], 0018h
  1124.         add    ds:[VaEdge+06h], 0018h
  1125.         add    ds:[VaEdge+08h], 0018h
  1126.         add    ds:[VaEdge+0ah], 0018h
  1127.         add    ds:[VaEdge+0ch], 0018h
  1128.         sub    ds:[VaEdge+0eh], 0018h
  1129.         call    VLift
  1130.         jmp    VAdvance_End
  1131. VAdvance_1:    cmp    ds:[Timer], 110h
  1132.         jae    VAdvance_2
  1133.         add    ds:[VBeta], 10h
  1134.         jmp    VAdvance_End
  1135. VAdvance_2:    cmp    ds:[Timer], 200h
  1136.         jne    VAdvance_2b
  1137.         call    Delay
  1138. VAdvance_2b:    jae    VAdvance_3
  1139.         sub    ds:[VBeta], 10h
  1140.         jmp    VAdvance_End
  1141. VAdvance_3:    cmp    ds:[Timer], 280h
  1142.         jne    VAdvance_3b
  1143.         call    Delay
  1144. VAdvance_3b:    jae    VAdvance_4
  1145.         call    VWater
  1146.         jmp    VAdvance_End
  1147. VAdvance_4:    cmp    ds:[Timer], 300h
  1148.         jne    VAdvance_4b
  1149.         call    Delay
  1150. VAdvance_4b:    jae    VAdvance_5
  1151.         call    VPull
  1152.         jmp    VAdvance_End
  1153. VAdvance_5:    cmp    ds:[Timer], 582h
  1154.         jae    VAdvance_6
  1155.         call    VWave
  1156.         jmp    VAdvance_End
  1157. VAdvance_6:    call    VFade
  1158.         call    VWave
  1159. VAdvance_End:    call    VRotate
  1160.         ret
  1161. VAdvance    ENDP
  1162.  
  1163. VBuild        PROC NEAR
  1164.         mov    ax, ds:[Vx2]
  1165.         sub    ax, ds:[Vx3]
  1166.         mov    ds:[Vdx], ax
  1167.         mov    bx, ds:[Vx1]
  1168.         mov    cx, ds:[Vx0]
  1169.         sub    bx, cx
  1170.         sub    cx, ds:[Vx3]
  1171.         sar    cx, 5
  1172.         mov    ds:[Vdx3], cx
  1173.         sub    bx, ax
  1174.         sar    bx, 7
  1175.         mov    ds:[Vddx], bx
  1176.  
  1177.         mov    ax, ds:[Vy2]
  1178.         mov    dx, ds:[Vy3]
  1179.         sub    ax, dx
  1180.         mov    ds:[Vdy], ax
  1181.         mov    bx, ds:[Vy1]
  1182.         mov    cx, ds:[Vy0]
  1183.         sub    bx, cx
  1184.         sub    cx, dx
  1185.         sar    cx, 5
  1186.         mov    ds:[Vdy3], cx
  1187.         sub    bx, ax
  1188.         sar    bx, 7
  1189.         mov    ds:[Vddy], bx
  1190.  
  1191.         mov    cx, ds:[Vx3]
  1192.         shl    cx, 2
  1193.         shl    dx, 2
  1194.         add    dh, 10
  1195.         mov    ax, ds:[Vdx]
  1196.         mov    bx, ds:[Vdy]
  1197.         mov    si, OFFSET aaColor
  1198.         mov    di, OFFSET aaLevel
  1199.         mov    bp, 128
  1200. VBuild_Loop2:    push    ax
  1201.         push    bx
  1202.         push    cx
  1203.         push    dx
  1204.         push    bp
  1205.  
  1206.         sar    ax, 5
  1207.         mov    WORD PTR cs:[OFFSET VBuild_Inc1 + 2], ax
  1208.         sar    bx, 5
  1209.         mov    WORD PTR cs:[OFFSET VBuild_Inc2 + 2], bx
  1210.         mov    bp, 128
  1211. VBuild_Loop1:    mov    bh, dh                ;  1
  1212.         mov    bl, ch                ;  1
  1213.         sub    bh, [di]            ;  1
  1214.         mov    al, [si]            ;  1
  1215.         inc    si                ;  1
  1216.         inc    di                ;  1
  1217.         mov    ah, al                ;  1
  1218.         mov    WORD PTR es:[bx], ax        ;  3
  1219.         mov    WORD PTR es:[bx+0100h], ax    ;  3
  1220.         mov    WORD PTR es:[bx+0200h], ax    ;  3
  1221.         mov    WORD PTR es:[bx+0300h], ax    ;  3
  1222.         mov    WORD PTR es:[bx+0400h], ax    ;  3
  1223. VBuild_Inc1:    add    cx, 01234h            ;  1
  1224.         jc    VBuild_EoL            ;  1
  1225. VBuild_Inc2:    add    dx, 01234h            ;  1
  1226.         dec    bp                ;  1
  1227.         jne    VBuild_Loop1            ;  3
  1228.                             ;=26
  1229. VBuild_EoL:    pop    bp
  1230.         pop    dx
  1231.         pop    cx
  1232.         pop    bx
  1233.         pop    ax
  1234.         add    cx, ds:[Vdx3]
  1235.         add    dx, ds:[Vdy3]
  1236.         add    ax, ds:[Vddx]
  1237.         add    bx, ds:[Vddy]
  1238.         dec    bp
  1239.         jne    VBuild_Loop2
  1240.         ret
  1241. VBuild        ENDP
  1242.  
  1243. VFade        PROC NEAR
  1244.         mov    dx, 03c8h
  1245.         mov    al, 40h
  1246.         out    dx, al
  1247.         inc    dx
  1248.         mov    cx, ds:[Timer]
  1249.         sub    cx, 580h
  1250.         shr    cx, 1
  1251.         mov    bx, cx
  1252.         mov    al, 0h
  1253. VFade_DAC1:    out    dx, al
  1254.         out    dx, al
  1255.         out    dx, al
  1256.         dec    cx
  1257.         jne    VFade_Dac1
  1258.         mov    cx, 40h
  1259.         sub    cx, bx
  1260.         xor    bx, bx
  1261. VFade_DAC2:    out    dx, al
  1262.         mov    al, bl
  1263.         shr    al, 1
  1264.         out    dx, al
  1265.         mov    al, bl
  1266.         out    dx, al
  1267.         mov    al, bh
  1268.         inc    bl
  1269.         dec    cx
  1270.         jne    VFade_DAC2
  1271.         ret
  1272. VFade        ENDP
  1273.  
  1274. VInit        PROC NEAR
  1275.         mov    di, OFFSET aaColor ; Use the colors of the zoom
  1276.         mov    si, 4040h
  1277.         mov    bp, 4000h
  1278.         mov    cl, 80h
  1279. VInit_Color2:    push    cx
  1280.         mov    cl, 80h
  1281. VInit_Color1:    mov    al, es:[si]
  1282.         mov    ds:[di], al
  1283.         mov    BYTE PTR ds:[di+(OFFSET aaLevel-OFFSET aaColor)], 00h
  1284.         mov    BYTE PTR fs:[bp], 00h
  1285.         inc    bp
  1286.         inc    si
  1287.         inc    di
  1288.         loop    VInit_Color1
  1289.         add    si, 0080h
  1290.         pop    cx
  1291.         loop    VInit_Color2
  1292.         xor    di, di        ; clear the background-buffer
  1293.         xor    ax, ax
  1294.         mov    cx, 8000h
  1295.         rep    stosw
  1296.         mov    cx, 128        ; distance = sqrt (x^2+y^2)
  1297. VInit_Sqrt3:    mov    bx, 128
  1298. VInit_Sqrt2:    mov    al, cl        ; calculate x^2
  1299.         sub    al, 128/2 + 1
  1300.         imul    al
  1301.         mov    si, ax
  1302.         mov    al, bl        ; calculate y^2
  1303.         sub    al, 128/2 + 1
  1304.         imul    al
  1305.         add    si, ax
  1306.         shl    esi, (SIN_BASE - 6) * 2    ; stretch distance according
  1307.         mov    ds:[qDummy], esi ; to the size of the sin-table
  1308.         mov    esi, SIN_SIZE
  1309.         xor    ebp, ebp
  1310. VInit_Sqrt1:    add    ebp, esi    ; get the square-root by testing each
  1311.         mov    eax, ebp    ; bit in the result, starting with the
  1312.         mul    eax        ; most significant one
  1313.         cmp    eax, ds:[qDummy]
  1314.         jna    VInit_Mark1
  1315.         sub    ebp, esi
  1316. VInit_Mark1:    shr    esi, 1
  1317.         jnc    VInit_Sqrt1
  1318.         mov    eax, ebp
  1319.         add    ax, ax        ; align the result to a word-boundary
  1320.         mov    fs:[di], ax
  1321.         add    di, 2
  1322.         dec    bx
  1323.         jne    VInit_Sqrt2    ; next column
  1324.         loop    VInit_Sqrt3    ; next row
  1325.  
  1326.         xor    di, di        ; get a sin-lookup-table with taylor
  1327.         xor    cx, cx        ; approximation
  1328. VInit_Sin:    mov    ebx, 51472    ; <-- that is pi/4 * 65536
  1329.         xor    eax, eax    ; calculate the x for sin(x)
  1330.         mov    ax, cx
  1331.         mul    ebx
  1332.         shr    eax, SIN_BASE
  1333.         mov    esi, eax    ; iteratively calculate the summands
  1334.         mov    ebp, eax    ; +x
  1335.         xor    bx, bx
  1336.         mov    bl, 6        ; -x^3 / 3!
  1337.         call    VTaylor
  1338.         sub    ebp, eax
  1339.         mov    bl, 20        ; +x^5 / 5!
  1340.         call    VTaylor
  1341.         add    ebp, eax
  1342.         mov    bl, 42        ; -x^7 / 7!
  1343.         call    VTaylor
  1344.         sub    ebp, eax
  1345.         mov    bl, 80        ; +x^9 / 9!
  1346.         call    VTaylor        ; take 80 > 8*9 to avoid overflow
  1347.         add    ebp, eax
  1348.         mov    ds:[OFFSET aSin0 + di], bp ;   sin(x)
  1349.         mov    ds:[OFFSET aSin2 + di], bp ; = sin(2pi+x)
  1350.         neg    di
  1351.         mov    ds:[OFFSET aSin1 + di], bp ; = sin(pi-x)
  1352.         neg    bp
  1353.         mov    ds:[OFFSET aSin2 + di], bp ; =-sin(2pi-x)
  1354.         neg    di
  1355.         mov    ds:[OFFSET aSin1 + di], bp ; =-sin(pi+x)
  1356.         add    di, 2        ; move pointer to next sin-place
  1357.         inc    cx
  1358.         cmp    cx, SIN_SIZE
  1359.         jna    VInit_Sin    ; loop to next calculation
  1360.         call    Delay
  1361.         mov    ds:[Timer], 0
  1362.         ret
  1363. VInit        ENDP
  1364.  
  1365. VLift        PROC NEAR
  1366.         mov    cx, 128*128
  1367.         mov    si, OFFSET aaColor
  1368.         mov    di, 4000h
  1369. VLift_Loop:    mov    al, 20h
  1370.         sub    al, ds:[si]
  1371.         add    al, al
  1372.         jc    VLift_Down
  1373.         add    fs:[di], al
  1374.         jnc    VLift_NoMove
  1375.         dec    BYTE PTR ds:[si+(OFFSET aaLevel-OFFSET aaColor)]
  1376.         jmp    VLift_NoMove
  1377. VLift_Down:    neg    al
  1378.         add    fs:[di], al
  1379.         jnc    VLift_NoMove
  1380.         inc    BYTE PTR ds:[si+(OFFSET aaLevel-OFFSET aaColor)]
  1381. VLift_NoMove:    inc    si
  1382.         inc    di
  1383.         dec    cx
  1384.         jne    VLift_Loop
  1385.         ret
  1386. VLift        ENDP
  1387.  
  1388. VPull        PROC NEAR
  1389.         mov    ax, ds:[Timer]
  1390.         and    al, 3
  1391.         jne    VPull_End
  1392.         mov    si, OFFSET aaLevel
  1393.         mov    cx, 4000h
  1394. VPull_Loop:    cmp    BYTE PTR ds:[si], 0
  1395.         je    VPull_Next
  1396.         dec    BYTE PTR ds:[si]
  1397.         jne    VPull_Next
  1398.         mov    BYTE PTR ds:[si+(OFFSET aaColor-OFFSET aaLevel)], 60h
  1399. VPull_Next:    inc    si
  1400.         dec    cx
  1401.         jne    VPull_Loop
  1402. VPull_End:    ret
  1403. VPull        ENDP
  1404.  
  1405. ;1) Drehung um die X-Achse mit Winkel a
  1406. ;2) Drehung um die Y-Achse mit Winkel b
  1407. ;
  1408. ;     ( 1    0      0   )
  1409. ;A1 = ( 0  cos a -sin a )
  1410. ;     ( 0  sin a  cos a )
  1411. ;
  1412. ;     ( cos b  sin b  0 )
  1413. ;A2 = (-sin b  cos b  0 )
  1414. ;     (   0      0    1 )
  1415. ;
  1416. ;       (    cos b          sin b     0   )   ( x )
  1417. ;A1*A2*v = (-cos a*sin b  cos a*cos b -sin a ) * ( y ) ; z=0
  1418. ;       (-sin a*sin b  sin a*cos b  cos a )   ( z )
  1419.  
  1420. VRotate        PROC NEAR
  1421.         mov    si, ds:[VAlpha]
  1422.         mov    di, ds:[VBeta]
  1423.         mov    bx, OFFSET VaEdge
  1424.         mov    bp, OFFSET Vx0
  1425.         mov    cx, 4
  1426. VRotate1:    push    cx
  1427.         mov    ax, ds:[di+SIN2COS]    ;  x*cos b
  1428.         mov    dx, ds:[bx]
  1429.         imul    dx
  1430.         mov    cx, dx
  1431.         mov    ax, ds:[di]        ; +y*sin b
  1432.         mov    dx, ds:[bx+2]
  1433.         imul    dx
  1434.         add    cx, dx
  1435.         mov    ds:[bp], cx
  1436.         mov    ax, ds:[si+SIN2COS]    ; x*cos a*sin b
  1437.         mov    dx, ds:[di]
  1438.         imul    dx
  1439.         sal    dx, 1
  1440.         mov    ax, ds:[bx]
  1441.         imul    dx
  1442.         neg    dx
  1443.         mov    cx, dx
  1444.         mov    ax, ds:[si+SIN2COS]    ; +y*cos a*cos b
  1445.         mov    dx, ds:[di+SIN2COS]
  1446.         imul    dx
  1447.         sal    dx, 1
  1448.         mov    ax, ds:[bx+2]
  1449.         imul    dx
  1450.         add    cx, dx
  1451.         mov    ds:[bp+2], cx
  1452.         mov    ax, ds:[si]        ; -x*sin a*sin b
  1453.         mov    dx, ds:[di]
  1454.         imul    dx
  1455.         sal    dx, 1
  1456.         mov    ax, ds:[bx]
  1457.         imul    dx
  1458.         neg    dx
  1459.         mov    cx, dx
  1460.         mov    ax, ds:[si]        ; y*sin a*cos b
  1461.         mov    dx, ds:[di+SIN2COS]
  1462.         imul    dx
  1463.         sal    dx,1
  1464.         mov    ax, ds:[bx+2]
  1465.         imul    dx
  1466.         add    cx, dx
  1467.         sar    cx, 1
  1468.         add    ch, 60h
  1469.         mov    ax, ds:[bp]        ; central projection in 
  1470.         imul    cx            ; x-direction
  1471.         add    dh, 20h
  1472.         mov    ds:[bp], dx
  1473.         mov    ax, ds:[bp+2]        ; central-projection in
  1474.         imul    cx            ; y-direction
  1475.         add    dh, 20h
  1476.         mov    ds:[bp+2], dx
  1477.         add    bx, 4
  1478.         add    bp, 4
  1479.         pop    cx
  1480.         dec    cx
  1481.         je    VRotate_End
  1482.         jmp    VRotate1
  1483. VRotate_End:    ret
  1484. VRotate        ENDP
  1485.  
  1486. VRun        PROC NEAR
  1487.         call    VAdvance
  1488.         call    VBuild
  1489.         call    VShow
  1490.         cmp    ds:[Timer], 05feh
  1491.         jna    VRun
  1492.         ret
  1493. VRun        ENDP
  1494.  
  1495. VShow        PROC NEAR
  1496.         call    Sync
  1497.         push    ds
  1498.         mov    ax, es
  1499.         add    ax, 04e3h
  1500.         mov    ds, ax
  1501.         xor    eax, eax
  1502.         xor    di, di
  1503.         xor    si, si
  1504.         mov    cx, ROWS
  1505. VShow_Copy2:    push    cx
  1506.         mov    cx, COLUMNS/2
  1507. VShow_Copy1:    mov    dl, ds:[si+1]
  1508.         mov    dh, dl
  1509.         shl    edx, 16
  1510.         mov    dl, ds:[si]
  1511.         mov    dh, dl
  1512.         mov    gs:[di], edx
  1513.         mov    ds:[si], ax
  1514.         add    di, 4
  1515.         add    si, 2
  1516.         dec    cx
  1517.         jne    VShow_Copy1
  1518.         pop    cx
  1519.         add    si, 96
  1520.         add    di, 192
  1521.         dec    cx
  1522.         jne    VShow_Copy2
  1523.         pop    ds
  1524.         ret
  1525. VShow        ENDP
  1526.  
  1527. VTaylor        PROC NEAR        ; get from one taylor-summand of
  1528.         mul    esi        ; sin to another by multiplicating
  1529.         shr    eax, 15        ; it with x^2 and dividing it by
  1530.         mul    esi        ; a suitable number
  1531.         shr    eax, 15
  1532.         idiv    ebx
  1533.         ret
  1534. VTaylor        ENDP
  1535.  
  1536. VWater        PROC NEAR
  1537.         mov    ax, ds:[Timer]
  1538.         and    ax, 7fh
  1539.         shr    ax, 2
  1540.         jc    VWater_End
  1541.         sub    ax, 1fh
  1542.         mov    si, OFFSET aaLevel
  1543.         mov    cx, 4000h
  1544. VWater_Loop:    cmp    ds:[si], al
  1545.         jnle    VWater_Ok
  1546.         inc    BYTE PTR ds:[si]
  1547.         mov    BYTE PTR ds:[si+(OFFSET aaColor-OFFSET aaLevel)], 60h
  1548. VWater_Ok:    inc    si
  1549.         dec    cx
  1550.         jne    VWater_Loop
  1551. VWater_End:    ret
  1552. VWater        ENDP
  1553.  
  1554. VWave        PROC NEAR
  1555.         mov    si, OFFSET aSin
  1556.         mov    bx, ds:[Timer]
  1557.         mov    bp, bx
  1558.         sub    bp, 300h
  1559.         cmp    bp, 7fh
  1560.         jna    VWave_Growth
  1561.         mov    bp, 7fh
  1562. VWave_Growth:    shl    bp, 9
  1563.         shl    bx, 8
  1564.         neg    bx
  1565.         mov    di, OFFSET aLevel
  1566.         mov    cx, 2*SIN_SIZE
  1567. VWave_Loop:    and    bx, 8*SIN_SIZE - 2
  1568.         mov    ax, ds:[si+bx]
  1569.         add    ah, 128
  1570.         mul    bp
  1571.         shr    bp, 1
  1572.         sub    dx, bp
  1573.         add    bp, bp
  1574.         mov    ds:[di], dx
  1575.         add    di, 2
  1576.         add    bx, 8
  1577.         dec    cx
  1578.         jne    VWave_Loop
  1579.  
  1580.         xor    bp, bp
  1581.         mov    di, OFFSET aaLevel
  1582.         mov    si, OFFSET aLevel
  1583.         mov    cx, 128*128
  1584. VWave_Level:    mov    bx, fs:[bp]
  1585.         mov    ax, ds:[si+bx]
  1586.         sub    dx, ax
  1587.         shr    dx, 5
  1588.         add    dl, 080h
  1589.         shr    dl, 2
  1590.         add    dl, 40h
  1591.         mov    ds:[OFFSET aaColor - OFFSET aaLevel + di], dl
  1592.         mov    dx, ax
  1593.         sar    ax, 11
  1594.         mov    ds:[di], al
  1595.         inc    di
  1596.         add    bp, 2
  1597.         dec    cx
  1598.         jne    VWave_Level
  1599.         mov    cx, 128
  1600.         mov    si, OFFSET aaColor
  1601. VWave_Adjust:    mov    al, ds:[si+1]
  1602.         mov    ds:[si], al
  1603.         add    si, 128
  1604.         dec    cx
  1605.         jne    VWave_Adjust
  1606.         ret
  1607. VWave        ENDP
  1608.  
  1609. INTRO_TEXT    ENDS
  1610.         END    Main
  1611.