home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Party 1994: Try This At Home
/
disk_image.bin
/
source
/
spam
/
spam.asm
< prev
next >
Wrap
Assembly Source File
|
1994-09-30
|
33KB
|
1,611 lines
.MODEL COMPACT
PAGE 65535, 132
STACK 100h ; stack-size
HUGE = 16384 ; used in ray-part
ROWS = 120 ; screen-height
COLUMNS = 160 ; screen-width
ZOOM_SIZE = 0100h ; border-length of zoom-data
SIN_BASE = 11 ; dual-logarithm of sin_size
SIN_SIZE = 1 SHL SIN_BASE ; sin-values in [0;pi/2[
CBOXCOLOR = 9 ; additional colors for rays
CPLANE = 3 ; planes for ray
_DATA SEGMENT PUBLIC 'DATA'
; initialized data
; general
Timer DW 0 ; timer -- clock of the intro
Rand DW 69 ; random number store
RandMax DW 16 ; random-amplitude
aCRT DW 00e11h ; most crt-registers must be
DW 00d06h
DW 03e07h
DW 0c109h
DW 0ea10h
DW 0df12h
DW 04013h
DW 0e715h
DW 00616h
CCRT = (OFFSET $ - OFFSET ACRT) / 2
; ray-part
include ray.inc ; data for ray-positions
aBoxColor DB 004h, 004h, 01ch ; blue
DB 03fh, 03fh, 004h ; brite yellow
DB 004h, 03fh, 007h ; green
DB 02fh, 02fh, 02fh ; brite grey
DB 01fh, 01fh, 01fh ; grey
DB 011h, 011h, 011h ; dark grey
DB 037h, 033h, 004h ; gold
DB 03fh, 004h, 004h ; red
DB 000h, 000h, 000h ; black
; box flying in the background
RaPlane1 DW 0h, 0h, 100h ; left side
DW 0h, 200h, 100h
DW 200h, 0h,-0c00h
DB 3, 1
DW 0h, 0h, -100h ; right side
DW 0h, 200h, 100h
DW 200h, 0h,-0c00h
DB 5, 0
DW 200h, 0h, 100h ; front side
DW 0h, 200h, 100h
DW 0h, 0h,-0c00h
DB 4, 0
; german flag flying in the foreground
RaPlane2 DW 300h, 0h, 100h ; black stripe
DW 0h, 0aah, 100h
DW 0h, 0h, -500h
DB 8, 0
DW 300h, 0h, 100h ; red stripe
DW 0h, 0aah, 55h
DW 0h, 0h, -500h
DB 7, 0
DW 300h, 0h, 100h ; gold stripe
DW 0h, 0aah, -55h
DW 0h, 0h, -500h
DB 6, 0
; box flying from back-right to front-left
RaPlane3 DW 0h, 0h, -100h ; right side
DW 0h, 200h, 100h
DW 200h, 0h,-0200h
DB 5, 0
DW 200h, 0h, 100h ; left side
DW 0h, 200h, 100h
DW 0h, 0h,-0200h
DB 4, 0
DW 0h, 0h, 100h ; front side
DW 0h, 200h, 100h
DW 200h, 0h,-0200h
DB 3, 1
; zoom-part
ZShrink DW 0ffffh ; zoom-quotient: ffff=min, 8000=max
ZLevel DW 20 ; count of zooms of the landscape
; voxel-part
VAlpha DW OFFSET aSin ; rotate-angle around x-axis
VBeta DW OFFSET aSin+2*SIN_SIZE+4; rotate-angle around y-axis
VaEdge DW -5555h,-5555h ; coordinated of the edge-points
DW -5555h, 5555h
DW 5555h, 5555h
DW 5555h,-5555h
Waver DW 0
; un-initialized data
; general
qDummy DD ? ; dummy, used in initialization
; ray-part
RaNormal DW CPLANE*3 DUP (?)
RpNormal DW ?
Rt DW ?
RpaPlane DW ?
RColor DB ?
RBackground DB ?
RcVisiblePlanes DW ?
Rtemp DW ?
Rc0 DW ?
Rc1 DW ?
Ry2 DW ?
Rx DW ?
Ry DW ?
Rr DW ?
Rl1 DW ?
Rl2 DW ?
Rts DW 8 DUP (?)
Rte DW 8 DUP (?)
R_a04 DW 200h
R_a24 DW 0h
Ra00 DW ?
Ra01 DW ?
Ra02 DW ?
Ra03 DW ?
Ra04 DW ?
Ra10 DW ?
Ra11 DW ?
Ra12 DW ?
Ra13 DW ?
Ra14 DW ?
Ra20 DW ?
Ra21 DW ?
Ra22 DW ?
Ra23 DW ?
Ra24 DW ?
; voxel-part
Vx0 DW ? ; mapped coordinates of the
Vy0 DW ? ; edge-points
Vx1 DW ?
Vy1 DW ?
Vx2 DW ?
Vy2 DW ?
Vx3 DW ?
Vy3 DW ?
Vdx1 DW ? ; differentials for display
Vdx2 DW ?
Vdx3 DW ?
Vdx DW ?
Vddx DW ?
Vdy1 DW ?
Vdy2 DW ?
Vdy3 DW ?
Vdy DW ?
Vddy DW ?
aSin = THIS WORD ; sin-values
aSin0 DW 2*SIN_SIZE DUP (?) ; area: [0.0*pi; 1.0*pi[
aSin1 DW 2*SIN_SIZE DUP (?) ; area: [1.0*pi; 2.0*pi[
aSin2 DW 1*SIN_SIZE+1 DUP (?); area: [2.0*pi; 3.0*pi]
SIN2COS = 2*SIN_SIZE
aaColor DB 128*128 DUP (?) ; colors of voxels
aaLevel DB 128*128 DUP (?) ; heights of voxels
aLevel DW 2*SIN_SIZE DUP (?) ; heights in sin-sample
_DATA ENDS
_DATA2 SEGMENT PUBLIC 'BSS' ; holds various stuff
DB 65535 DUP (?)
_DATA2 ENDS
_DATA3 SEGMENT PUBLIC 'BSS' ; holds various stuff
DB 65535 DUP (?)
_DATA3 ENDS
INTRO_TEXT SEGMENT PUBLIC 'CODE'
ASSUME CS:INTRO_TEXT; DS:_DATA; ES:_DATA2
; ============================================================================
; Routines that are not part-specific
; ============================================================================
.286
ynSync DB 0 ; boolean, indication new frame
pTimerOld = THIS DWORD ; pointer to system timer-handler
offTimerOld DW ?
segTimerOld DW ?
Timer_Counter DW 0 ; system-timer-handler on overflow!
BubbleSort PROC
mov cx, RcVisiblePlanes
BS_Loop1: dec cx
jle BS_End
push si
push cx
BS_Loop2: mov ax, ds:[si]
cmp ax, ds:[si+2]
jng BS_NoSwap
xchg ax, ds:[si+2]
mov ds:[si], ax
BS_NoSwap: add si, 2
dec cx
jne BS_Loop2
pop cx
pop si
dec cx
jmp BS_Loop1
BS_End: ret
BubbleSort ENDP
Delay PROC NEAR
pushf
mov cx, 70
Delay_Loop: call Sync
loop Delay_Loop
sub ds:[Timer], 70
popf
ret
Delay ENDP
MDone PROC NEAR ; clear-up everything
mov dx, 0043h ; slow-down the system-clock to
mov al, 34h ; it's common speed - 18.2 Hz
out dx, al
mov dl, 40h
mov al, 00h
out dx, al
out dx, al
mov ax, 2508h ; restore the old timer-interrupt
mov dx, cs:[segTimerOld] ; handler
mov ds, dx
mov dx, cs:[offTimerOld]
int 21h
mov ax, 0003h ; switch back to text-mode
int 10h
mov ah, 01h ; clear keyboard-buffer
int 16h
jz MDone_NoKey
mov ah, 00h
int 16h
MDone_NoKey: mov ax, 4c00h ; quit the program
int 21h
MDone ENDP
MInit PROC NEAR
ASSUME DS:INTRO_TEXT
push cs ; set-up segments
pop ds
cld
mov ax, 3508h ; store old timer-interrupt
int 21h
mov ds:[offTimerOld], bx
mov ds:[segTimerOld], es
mov ah, 25h ; redirect timer-interrupt
mov dx, OFFSET TimerHandler
int 21h
mov dx, 0043h ; set new speed of timer
mov al, 34h ; to approx. 70 Hz
out dx, al
mov dl, 40h
mov al, 95h
out dx, al
mov al, 42h
out dx, al
ASSUME DS:_DATA
mov ax, SEG _DATA
mov ds, ax
mov ax, 0013h ; init standard mode13
int 10h
mov dx, 03c4h
mov dx, 03c2h
mov al, 0e3h ; increase y-resolution to 60%
out dx, al
mov dx, 03d4h
mov si, OFFSET aCRT
mov cx, CCRT
rep outsw
mov dx, 03c8h ; adress DAC-controller
xor ax, ax
out dx, al
inc dl
xor bx, bx ; fill the first 64 DAC-registers
mov cx, 40h ; with colors, ranging from black
MInit_DAC1: out dx, al ; to green
mov al, bl
out dx, al
mov al, bh
out dx, al
inc bl
loop MInit_DAC1
xor bl, bl
mov cx, 40h ; fill the next 64 DAC-registers with
MInit_DAC2: out dx, al ; colors, ranging from black to blue
mov al, bl
shr al, 1
out dx, al
mov al, bl
out dx, al
mov al, bh
inc bl
loop MInit_DAC2
mov si, OFFSET aBoxColor
mov cx, CBOXCOLOR*3
rep outsb
mov ax, 0a000h
.386
mov gs, ax
.286
ret
MInit ENDP
Main PROC NEAR ; start-point of intro
call MInit ; MInitialization
call RRun ; show the ray-part
call ZInit ; show the zoom-part
call ZRun
call VInit ; show the voxel-part
call VRun
jmp MDone ; clear-up everything
Main ENDP
Random PROC NEAR ; this is just a simple random
push ax ; number generator, that yields a
push dx ; random-number in bp, while leaving
mov ax, ds:[rand] ; all other registers unchanged
mov dx, 4217h
imul dx
xor ax, 1974h
mov ds:[rand], ax
mov dx, RandMax
imul dx
mov bp, dx
pop dx
pop ax
ret
Random ENDP
Sqrt PROC
mov bx, ax
mov dl, 40h
xor cx, cx
Sqrt_TryNext: xor cl, dl
mov al, cl
mul al
cmp ax, bx
jle Sqrt_TakeIt
xor cl, dl
Sqrt_TakeIt: shr dl, 1
jnz Sqrt_TryNext
mov si, cx
ret
Sqrt ENDP
Sync PROC NEAR
cmp cs:[ynSync], 0 ; wait for a new frame ...
je Sync
mov cs:[ynSync], 0 ; now it's an old frame
inc ds:[Timer] ; enhance timer
Sync_End: push ax
mov ah, 01h
int 16h
jz Sync_Done
jmp MDone
Sync_Done: pop ax
ret
Sync ENDP
TimerHandler PROC FAR
mov cs:[ynSync], 1 ; report a new frame
add cs:[Timer_Counter], 4295h ; call the system-timer-
jc Timer_UseOld ; interrupt if it's time again
push ax
mov al, 20h ; acknowledge the interrupt to
out 20h, al ; the irq-controller
pop ax
iret
Timer_UseOld: jmp cs:[pTimerOld] ; call system-timer-handler
TimerHandler ENDP
; ============================================================================
; routines for the ray-tracing-part
; ============================================================================
RAnimate PROC
call Sync
mov dx, Rt
push ds
mov bx, seg _DATA2
neg bx
mov WORD PTR cs:RAnimate_Poke, bx
neg bx
xor si, si
mov dx, Rt
mov bp, ROWS
RAnimate_Loop1: mov cx, COLUMNS
RAnimate_Loop2: mov ds, bx
cmp [si], dx
jle RAnimate_Move
RAnimate_Next: inc bx
dec cx
jne RAnimate_Loop2
add WORD PTR cs:[RAnimate_Poke], 256-COLUMNS
dec bp
jne RAnimate_Loop1
pop ds
ret
RAnimate_Move: mov ax, [si]
and al, 0fh
or al, 80h
.386
mov ah, al
push bx
add bx, 1234h
RAnimate_Poke = $-2
add bx, bx
mov gs:[bx], ax
pop bx
.286
RAnimate_More: mov ax, [si+2]
mov [si], ax
cmp ax, 07fffh
je RAnimate_Moved
add si, 2
jmp RAnimate_More
RAnimate_Moved: xor si, si
jmp RAnimate_Next
RAnimate ENDP
RFade1 PROC
mov si, OFFSET aBoxColor
mov cx, CBOXCOLOR*3
mov dx, 03c8h
mov al, 80h
out dx, al
inc dx
RFade1_Loop1: inc BYTE PTR ds:[si]
lodsb
cmp al, 3fh
jna RFade1_Ok
mov al, 3fh
RFade1_Ok: out dx, al
loop RFade1_Loop1
ret
RFade1 ENDP
RFade2 PROC
mov dx, 03c8h
mov al, 25h
out dx, al
inc dx
mov ax, 3fh
sub ax, Timer
out dx, al
mov ah, al
cmp al, 0e5h
jae RFade2_Ok
mov al, 0e5h
RFade2_Ok: out dx, al
mov al, ah
out dx, al
mov ax, Timer
sub al, 40h
shr al, 1
cmp al, 10h
jae RFade2_End
xor ah, ah
mov si, ax
mov di, COLUMNS-1
sub di, si
add si, si
add di, di
mov cx, ROWS
RFade2_Loop: .386
mov WORD PTR gs:[si], 0000h
mov WORD PTR gs:[di], 0000h
add si, 0200h
add di, 0200h
.286
loop RFade2_Loop
RFade2_End: ret
RFade2 ENDP
RInit PROC
mov ax, SEG _DATA
mov ds, ax
mov es, ax
call RNormalize
mov ax, SEG _DATA2
.386
mov fs, ax
.286
xor di, di
mov Ry, -ROWS/2
RInit_NRow: mov Rx, -COLUMNS/2
RInit_NColumn: mov RBackground, 0
mov ax, Ry ; get the "distance" r to the z-axis
imul Ry
mov cx, ax ; y^2
mov ax, Rx
imul Rx
add ax, cx ; +x^2
call Sqrt ; sqrt
mov Rr, si
add si, si
jne RInit_NoMid
jmp RInit_Cont ; so we dont have /0 below
RInit_NoMid: add si, OFFSET aDr
mov bx, [si] ; get the angle of the (fracted?) ray
mov ax, bx ; calculate the angle to y-z-plane
mov dx, [si+OFFSET aZ - OFFSET aDr]
mov Ry2, dx
imul Rx
idiv Rr
mov Rc0, ax
mov bp, ax
mov ax, bx ; calculate the angle to x-z-plane
imul Ry
idiv Rr
neg ax ; flip the ray in y-direction
mov Rc1, ax ; (coz 0;0 is at the TOP of the screen)
mov bx, ax ; if the ray descends very slow, it
cmp bx, 16 ; won't intersect the checkered plane
jng RInit_Cont
mov dx, 2 ; 2/dy = l = units in z-direction till
xor ax, ax ; the ray intersects the plane
div bx
mov cx, ax
imul bp ; l*dx is the x-coordinate of the point
mov ax, cx
add si, OFFSET aZ-OFFSET aDr ; l+"z-coordinate of the point
add ax, Ry2 ; where the ray crosses the z-axis"
sar ax, 8 ; is the z-coordinate
cmp dx, 13 ; x < 13 - the borders of the plane
jge RInit_Cont
cmp dx, -13 ; x > -13
jl RInit_Cont
cmp ax, 22 ; z < 22
jge RInit_Cont
cmp ax, -2 ; z > -2
jl RInit_Cont
shr ax, 1 ; make checkers 2*x units large
shr dx, 1
adc ax, dx
and al, 1 ; 1/0 is the color here
inc al
mov RBackground, al
RInit_Cont: mov ds:[Rtemp], di
mov ds:[RpNormal], OFFSET RaNormal
mov bp, OFFSET Rts
mov RcVisiblePlanes, 0
mov si, RpaPlane ; Fill in the plane-coordinates
mov cx, CPLANE
RInit_NextWall: push cx
mov di, ds:[RpNormal]; check with the common scalar-
mov ax, ds:[Rc0] ; product if the wall is visible
imul WORD PTR ds:[di] ; at all
mov cl, ah
mov ch, dl
mov ax, ds:[Rc1]
imul WORD PTR ds:[di+2]
add cl, ah
adc ch, dl
add cx, ds:[di+4]
sub cx, 10h ; be a little bit conservative
cmp cx, 0
jns RInit_Section
add si, 20
jmp RInit_NoSect
RInit_Section: mov di, OFFSET Ra00 ; into the equations for the
mov cx, 3 ; intersection-algorithm
RInit_FillIn: movsw
movsw
add di, 2
movsw
add di, 2
dec cx
jne RInit_FillIn
lodsw
mov RColor, al
push si
call RSec
pop si
cmp ax, bx
jg RInit_NoSect
shl ax, 4
shl bx, 4
or al, RColor
or bl, RColor
mov ds:[bp], ax
mov ds:[bp+OFFSET Rte-OFFSET Rts], bx
inc RcVisiblePlanes
add bp, 2
RInit_NoSect: pop cx
add ds:[RpNormal], 6
dec cx
jne RInit_NextWall
mov si, OFFSET Rts
call BubbleSort
mov si, OFFSET Rte
call BubbleSort
call RPack
.386
mov ax, fs
inc ax
mov fs, ax
.286
mov di, ds:[Rtemp]
mov al, RBackground
or al, 80h
.386
mov ah, al
mov gs:[di], ax
add di, 2
.286
inc Rx
cmp Rx, COLUMNS/2
je RInit_NextR
jmp RInit_NColumn
RInit_NextR:
add di, 2*(256-COLUMNS)
inc Ry
cmp Ry, ROWS/2
je RInit_Done
jmp RInit_NRow
RInit_Done: ret
RInit ENDP
RNormalize PROC
mov si, RpaPlane ; RInitialize normal-vectors
mov di, OFFSET RaNormal
mov cx, CPLANE
RNormalize_Loop:mov ax, ds:[si+6] ; x2*y3
imul WORD PTR ds:[si+14]
mov bl, ah
mov bh, dl
mov ax, ds:[si+12] ; -x3*y2
imul WORD PTR ds:[si+8]
sub bl, ah
sbb bh, dl
mov ds:[di], bx ; = z1
mov ax, ds:[si+12] ; x3*y1
imul WORD PTR ds:[si+2]
mov bl, ah
mov bh, dl
mov ax, ds:[si] ; -x1*y3
imul WORD PTR ds:[si+14]
sub bl, ah
sbb bh, dl
mov ds:[di+2], bx ; = z2
mov ax, ds:[si] ; x1*y2
imul WORD PTR ds:[si+8]
mov bl, ah
mov bh, dl
mov ax, ds:[si+6] ; -x2*y1
imul WORD PTR ds:[si+2]
sub bl, ah
sbb bh, dl
mov ds:[di+4], bx ; = z3
cmp BYTE PTR ds:[si+19], 0
je RNormalize_Ok
neg WORD PTR ds:[di]
neg WORD PTR ds:[di+2]
neg WORD PTR ds:[di+4]
RNormalize_Ok: add si, 20
add di, 6
loop RNormalize_Loop
ret
RNormalize ENDP
RPack PROC
xor di, di
mov cx, RcVisiblePlanes
or cx, cx
je RPack_Void
mov si, OFFSET Rts
RPack_Loop: lodsw
.386
mov fs:[di], ax
.286
add di, 2
dec cx
jne RPack_Loop
mov ax, ds:[si+OFFSET Rte-OFFSET Rts-2]
and al, 0f0h
or al, RBackground
.386
mov fs:[di], ax
.386
add di, 2
RPack_Void: .386
mov WORD PTR fs:[di], 07fffh
.286
ret
RPack ENDP
RRun PROC
cmp Timer, 0 ; first animation-part
jne RRun_1b
mov Rt, -4000h
mov RpaPlane, OFFSET RaPlane1
mov R_a04, 400h
mov R_a24, 0
call RInit
RRun_1b: cmp Timer, 100h
jae RRun_2
add Rt, 084h
call RAnimate
jmp RRun_End
RRun_2: cmp Timer, 100h
jne RRun_2b
mov Rt, -4200h
mov RpaPlane, OFFSET RaPlane2
mov R_a04, 200h
mov R_a24, 0h
call RInit
RRun_2b: cmp Timer, 200h
jae RRun_3
add Rt, 100h
call RAnimate
jmp RRun_End
RRun_3: cmp Timer, 200h
jne RRun_3b
mov Rt, -2000h
mov RpaPlane, OFFSET RaPlane3
mov R_a04, -400h
mov R_a24, 300h
call RInit
RRun_3b: cmp Timer, 300h
jae RRun_4
add Rt, 080h
call RAnimate
jmp RRun_End
RRun_4: cmp Timer, 340h
jae RRun_4b
call RFade1
call Sync
jmp RRun_End
RRun_4b: cmp Timer, 340h
jne RRun_5
call RFade2
call RWhite
RRun_5: cmp Timer, 380h
jae RRun_End
call RFade2
call Sync
RRun_End: cmp Timer, 380h
.386
jl RRun
.286
ret
RRun ENDP
RSec PROC
mov ax, Rc0 ; fill in the variables for c
neg ax
mov Ra02, ax
mov ax, Rc1
neg ax
mov Ra12, ax
mov Ra22, -100h
mov ax, Ry2 ; fill in the variables for y
add Ra23, ax
mov ax, R_a04 ; fill in the "time" vector
mov Ra04, ax
mov ax, R_a24
mov Ra24, ax
mov Ra14, 0
mov cx, 2
mov si, OFFSET Ra00
RSec_LoopI: mov bx, 0
RSec_LoopJ: cmp bx, 4
je RSec_Skip1
mov ax, ds:[OFFSET Ra20+bx]
imul WORD PTR ds:[si+4]
mov dh, dl
mov dl, ah
add ds:[si+bx], dx
RSec_Skip1: add bx, 2
cmp bx, 10
jne RSec_LoopJ
add si, 10
dec cx
jne RSec_LoopI
; * * 0 * *
; * * 0 * *
; * * -1 * *
cmp Ra01, 0
je RSec_Idle1
cmp Ra11, 0
jne RSec_Mark1
mov ax, Ra00
xchg ax, Ra10
mov Ra00, ax
mov ax, Ra01
xchg ax, Ra11
mov Ra01, ax
mov ax, Ra03
xchg ax, Ra13
mov Ra03, ax
mov ax, Ra04
xchg ax, Ra14
mov Ra04, ax
jmp RSec_Idle1
RSec_Mark1: mov cx, 5
mov si, OFFSET Ra00
RSec_Loop3: cmp cx, 4
je RSec_Skip2
cmp cx, 3
je RSec_Skip2
mov ax, ds:[si]
imul Ra11
mov bh, dl
mov bl, ah
mov ax, ds:[si+10]
imul Ra01
sub bl, ah
sbb bh, dl
mov ds:[si], bx
RSec_Skip2: add si, 2
dec cx
jne RSec_Loop3
mov Ra01, 0
; * 0 0 * *
; * * 0 * *
; * * -1 * *
RSec_Idle1: cmp Ra00, 0
je RSec_Short1
mov si, OFFSET Ra01
mov cx, 4
RSec_Loop4: cmp cx, 3
je RSec_Skip3
mov ax, ds:[si+10]
imul Ra00
mov bh, dl
mov bl, ah
mov ax, ds:[si]
imul Ra10
sub bl, ah
sbb bh, dl
mov ds:[si+10], bx
RSec_Skip3: add si, 2
dec cx
jne RSec_Loop4
; * 0 0 * *
; 0 * 0 * *
; * * -1 * *
RSec_Short1: cmp Ra04, 0
jne RSec_NoZero1
mov ax, Ra03
mov dx, Ra00
or ax, ax
jns RSec_NoSign1
neg ax
neg dx
RSec_NoSign1: or dx, dx
js RSec_JumpX
cmp dx, ax
jl RSec_JumpX
mov Rl1, -HUGE
mov Rl2, HUGE
jmp RSec_Done1
RSec_JumpX: jmp RSec_NoSection
RSec_NoZero1: mov ax, Ra03
mov dx, -100h
imul dx
idiv Ra04
mov bx, ax
mov ax, Ra00
sub ax, Ra03
mov dx, 100h
imul dx
idiv Ra04
cmp bx, ax
jg RSec_NoSwap1
xchg bx, ax
RSec_NoSwap1: mov Rl1, ax
mov Rl2, bx
RSec_Done1: cmp Ra14, 0
jne RSec_NoZero2
mov ax, Ra13
mov dx, Ra11
or ax, ax
jns RSec_NoSign2
neg ax
neg dx
RSec_NoSign2: or dx, dx
js RSec_NoSection
cmp dx, ax
jl RSec_NoSection
mov ax, -HUGE
mov bx, HUGE
jmp RSec_Done2
RSec_NoZero2: mov ax, Ra13
mov dx, -100h
imul dx
idiv Ra14
mov bx, ax
mov ax, Ra11
sub ax, Ra13
mov dx, 100h
imul dx
idiv Ra14
cmp bx, ax
jg RSec_Done2
xchg bx, ax
RSec_Done2: cmp ax, Rl1
jg RSec_NoChange1
mov ax, Rl1
RSec_NoChange1: cmp bx, Rl2
jl RSec_NoChange2
mov bx, Rl2
RSec_NoChange2: ret
RSec_NoSection: xor ax, ax
xor bx, bx
dec bx
ret
RSec ENDP
RWhite PROC
push es
.386
push gs
.286
pop es
mov ax, 2525h
xor di, di
mov cx, 256*ROWS
rep stosw
pop es
ret
RWhite ENDP
; ============================================================================
; routines for the zoom-part
; ============================================================================
yZoom DW 0
ZInit PROC NEAR
xor al, al
mov dx, SEG _DATA3 ; Initialize height with 40h
mov es, dx ; use fs as the "new" buffer segment
xor di, di
mov ax, 2525h
mov cx, 8000h
rep stosw
.386
mov ax, SEG _DATA2 ; use es as the "old" buffer segment
mov fs, ax
mov Timer, 0
ret
ZInit ENDP
ZRun PROC NEAR
ZRun_Start: mov ds:[ZShrink], 0ffffh ; reset the zoom-factor each stage
xor ah, ah
mov cx, ZOOM_SIZE/2 ; Zoom old _DATA2 into the new _DATA2;
mov si, ZOOM_SIZE/4*(ZOOM_SIZE+1) ; the inner quarter is
xor di, di ; magnified to whold size, so that only
ZRun_Zoom2: push cx ; the wholes have to be filled
mov cx, ZOOM_SIZE/2
ZRun_Zoom1: push cx
mov al, es:[si+ZOOM_SIZE+1] ; get the heights of four
cbw ; points that build a square
mov dx, ax
mov al, es:[si+ZOOM_SIZE]
cbw
mov cx, ax
mov al, es:[si+1]
cbw
mov bx, ax
mov al, es:[si]
cbw
mov fs:[di], al ; just copy the point at the top-left
push bx ; interpolate and randomly displace
add bx, ax ; the point at the top-middle
sar bx, 1
call Random
add bx, bp
mov fs:[di+1], bl
add cx, ax ; interpolate and randomly displace
push cx ; the point at the left-middle
sar cx, 1
call Random
add cx, bp
mov fs:[di+ZOOM_SIZE], cl
pop cx ; interpolate and randomly displace
pop bx ; the point at the center
add dx, bx
add dx, cx
sar dx, 2
call Random
add dx, bp
mov fs:[di+ZOOM_SIZE+1], dl
inc si ; move to next column
add di, 2
pop cx
dec cx
jne ZRun_Zoom1 ; loop to next column
add si, ZOOM_SIZE/2 ; move pointers to next row
add di, ZOOM_SIZE
pop cx ; check if it's time to refresh
push cx ; the display
test cx, 3
jne ZRun_NoRefresh
push si
push di
call ZShow ; draw the next picture
mov ax, ds:[ZShrink]; recalculate the zoom-factor
mov dx, 64136
mul dx
mov ds:[ZShrink], dx
pop di
pop si
ZRun_NoRefresh: pop cx ; loop to next row
dec cx
jne ZRun_Zoom2
call Random ; avoid cycles in randomness
cmp ds:[ZLevel], 6
ja ZRun_ItsOK
sub ds:[RandMax], 3 ; fractal-dimension <2.5 ...
ZRun_ItsOK: mov ds:[ZShrink], 0ffffh ; reset the zoom-factor each stage
mov ax, es ; swap between display- and calculation
mov dx, fs ; _DATA2
xchg ax, dx
mov es, ax
mov fs, dx
dec ds:[ZLevel] ; do a few loops
jne ZRun_Start
mov ax, 1409
ZRun_Slow: push ax
call ZShow
pop ax
sub ds:[ZShrink], ax
sub ax, 31
jnc ZRun_Slow
mov ds:[ZShrink], 8000h
ZRun ENDP
ZShow PROC NEAR
call Sync
ZShow_NoExpand: mov ax, ds:[ZShrink]
push ax
neg ax
push ax
mov dx, ZOOM_SIZE/2
mul dx
add ax, 8000h
adc dx, 0000h
mov cs:[yZoom], ax
mov ax, ZOOM_SIZE
mul dx
mov si, ax
pop ax
mov dx, ZOOM_SIZE/2
mul dx
add ax, 8000h
adc dx, 0000h
mov bp, ax
add si, dx
pop dx
add dx, dx
push ds
mov di, (ROWS-ZOOM_SIZE/2) SHL 8 + (COLUMNS-ZOOM_SIZE/2)
mov cx, ZOOM_SIZE/2
push es
pop ds
ZShow_Loop2: push cx
push si
mov bx, bp
mov cx, ZOOM_SIZE/4
ZShow_Loop1: mov al, ds:[si]
add bx, dx
adc si, 1
mov ah, al
mov gs:[di], ax
add di, 2
mov al, ds:[si]
mov ah, al
mov gs:[di], ax
add bx, dx
adc si, 1
add di, 2
dec cx
jne ZShow_Loop1
pop si
add cs:[yZoom], dx
jnc ZShow_NoSkip
add si, ZOOM_SIZE
ZShow_NoSkip: add si, ZOOM_SIZE
add di, 512-ZOOM_SIZE
xor bx, bx
pop cx
dec cx
jne ZShow_Loop2
pop ds
ret
ZShow ENDP
; ============================================================================
; routines for the voxel-part
; ============================================================================
VAdvance PROC NEAR
cmp ds:[Timer], 080h
jne VAdvance_0b
call Delay
VAdvance_0b: jae VAdvance_1
add ds:[VAlpha], 18h
sub ds:[VaEdge+00h], 0018h
sub ds:[VaEdge+02h], 0018h
sub ds:[VaEdge+04h], 0018h
add ds:[VaEdge+06h], 0018h
add ds:[VaEdge+08h], 0018h
add ds:[VaEdge+0ah], 0018h
add ds:[VaEdge+0ch], 0018h
sub ds:[VaEdge+0eh], 0018h
call VLift
jmp VAdvance_End
VAdvance_1: cmp ds:[Timer], 110h
jae VAdvance_2
add ds:[VBeta], 10h
jmp VAdvance_End
VAdvance_2: cmp ds:[Timer], 200h
jne VAdvance_2b
call Delay
VAdvance_2b: jae VAdvance_3
sub ds:[VBeta], 10h
jmp VAdvance_End
VAdvance_3: cmp ds:[Timer], 280h
jne VAdvance_3b
call Delay
VAdvance_3b: jae VAdvance_4
call VWater
jmp VAdvance_End
VAdvance_4: cmp ds:[Timer], 300h
jne VAdvance_4b
call Delay
VAdvance_4b: jae VAdvance_5
call VPull
jmp VAdvance_End
VAdvance_5: cmp ds:[Timer], 582h
jae VAdvance_6
call VWave
jmp VAdvance_End
VAdvance_6: call VFade
call VWave
VAdvance_End: call VRotate
ret
VAdvance ENDP
VBuild PROC NEAR
mov ax, ds:[Vx2]
sub ax, ds:[Vx3]
mov ds:[Vdx], ax
mov bx, ds:[Vx1]
mov cx, ds:[Vx0]
sub bx, cx
sub cx, ds:[Vx3]
sar cx, 5
mov ds:[Vdx3], cx
sub bx, ax
sar bx, 7
mov ds:[Vddx], bx
mov ax, ds:[Vy2]
mov dx, ds:[Vy3]
sub ax, dx
mov ds:[Vdy], ax
mov bx, ds:[Vy1]
mov cx, ds:[Vy0]
sub bx, cx
sub cx, dx
sar cx, 5
mov ds:[Vdy3], cx
sub bx, ax
sar bx, 7
mov ds:[Vddy], bx
mov cx, ds:[Vx3]
shl cx, 2
shl dx, 2
add dh, 10
mov ax, ds:[Vdx]
mov bx, ds:[Vdy]
mov si, OFFSET aaColor
mov di, OFFSET aaLevel
mov bp, 128
VBuild_Loop2: push ax
push bx
push cx
push dx
push bp
sar ax, 5
mov WORD PTR cs:[OFFSET VBuild_Inc1 + 2], ax
sar bx, 5
mov WORD PTR cs:[OFFSET VBuild_Inc2 + 2], bx
mov bp, 128
VBuild_Loop1: mov bh, dh ; 1
mov bl, ch ; 1
sub bh, [di] ; 1
mov al, [si] ; 1
inc si ; 1
inc di ; 1
mov ah, al ; 1
mov WORD PTR es:[bx], ax ; 3
mov WORD PTR es:[bx+0100h], ax ; 3
mov WORD PTR es:[bx+0200h], ax ; 3
mov WORD PTR es:[bx+0300h], ax ; 3
mov WORD PTR es:[bx+0400h], ax ; 3
VBuild_Inc1: add cx, 01234h ; 1
jc VBuild_EoL ; 1
VBuild_Inc2: add dx, 01234h ; 1
dec bp ; 1
jne VBuild_Loop1 ; 3
;=26
VBuild_EoL: pop bp
pop dx
pop cx
pop bx
pop ax
add cx, ds:[Vdx3]
add dx, ds:[Vdy3]
add ax, ds:[Vddx]
add bx, ds:[Vddy]
dec bp
jne VBuild_Loop2
ret
VBuild ENDP
VFade PROC NEAR
mov dx, 03c8h
mov al, 40h
out dx, al
inc dx
mov cx, ds:[Timer]
sub cx, 580h
shr cx, 1
mov bx, cx
mov al, 0h
VFade_DAC1: out dx, al
out dx, al
out dx, al
dec cx
jne VFade_Dac1
mov cx, 40h
sub cx, bx
xor bx, bx
VFade_DAC2: out dx, al
mov al, bl
shr al, 1
out dx, al
mov al, bl
out dx, al
mov al, bh
inc bl
dec cx
jne VFade_DAC2
ret
VFade ENDP
VInit PROC NEAR
mov di, OFFSET aaColor ; Use the colors of the zoom
mov si, 4040h
mov bp, 4000h
mov cl, 80h
VInit_Color2: push cx
mov cl, 80h
VInit_Color1: mov al, es:[si]
mov ds:[di], al
mov BYTE PTR ds:[di+(OFFSET aaLevel-OFFSET aaColor)], 00h
mov BYTE PTR fs:[bp], 00h
inc bp
inc si
inc di
loop VInit_Color1
add si, 0080h
pop cx
loop VInit_Color2
xor di, di ; clear the background-buffer
xor ax, ax
mov cx, 8000h
rep stosw
mov cx, 128 ; distance = sqrt (x^2+y^2)
VInit_Sqrt3: mov bx, 128
VInit_Sqrt2: mov al, cl ; calculate x^2
sub al, 128/2 + 1
imul al
mov si, ax
mov al, bl ; calculate y^2
sub al, 128/2 + 1
imul al
add si, ax
shl esi, (SIN_BASE - 6) * 2 ; stretch distance according
mov ds:[qDummy], esi ; to the size of the sin-table
mov esi, SIN_SIZE
xor ebp, ebp
VInit_Sqrt1: add ebp, esi ; get the square-root by testing each
mov eax, ebp ; bit in the result, starting with the
mul eax ; most significant one
cmp eax, ds:[qDummy]
jna VInit_Mark1
sub ebp, esi
VInit_Mark1: shr esi, 1
jnc VInit_Sqrt1
mov eax, ebp
add ax, ax ; align the result to a word-boundary
mov fs:[di], ax
add di, 2
dec bx
jne VInit_Sqrt2 ; next column
loop VInit_Sqrt3 ; next row
xor di, di ; get a sin-lookup-table with taylor
xor cx, cx ; approximation
VInit_Sin: mov ebx, 51472 ; <-- that is pi/4 * 65536
xor eax, eax ; calculate the x for sin(x)
mov ax, cx
mul ebx
shr eax, SIN_BASE
mov esi, eax ; iteratively calculate the summands
mov ebp, eax ; +x
xor bx, bx
mov bl, 6 ; -x^3 / 3!
call VTaylor
sub ebp, eax
mov bl, 20 ; +x^5 / 5!
call VTaylor
add ebp, eax
mov bl, 42 ; -x^7 / 7!
call VTaylor
sub ebp, eax
mov bl, 80 ; +x^9 / 9!
call VTaylor ; take 80 > 8*9 to avoid overflow
add ebp, eax
mov ds:[OFFSET aSin0 + di], bp ; sin(x)
mov ds:[OFFSET aSin2 + di], bp ; = sin(2pi+x)
neg di
mov ds:[OFFSET aSin1 + di], bp ; = sin(pi-x)
neg bp
mov ds:[OFFSET aSin2 + di], bp ; =-sin(2pi-x)
neg di
mov ds:[OFFSET aSin1 + di], bp ; =-sin(pi+x)
add di, 2 ; move pointer to next sin-place
inc cx
cmp cx, SIN_SIZE
jna VInit_Sin ; loop to next calculation
call Delay
mov ds:[Timer], 0
ret
VInit ENDP
VLift PROC NEAR
mov cx, 128*128
mov si, OFFSET aaColor
mov di, 4000h
VLift_Loop: mov al, 20h
sub al, ds:[si]
add al, al
jc VLift_Down
add fs:[di], al
jnc VLift_NoMove
dec BYTE PTR ds:[si+(OFFSET aaLevel-OFFSET aaColor)]
jmp VLift_NoMove
VLift_Down: neg al
add fs:[di], al
jnc VLift_NoMove
inc BYTE PTR ds:[si+(OFFSET aaLevel-OFFSET aaColor)]
VLift_NoMove: inc si
inc di
dec cx
jne VLift_Loop
ret
VLift ENDP
VPull PROC NEAR
mov ax, ds:[Timer]
and al, 3
jne VPull_End
mov si, OFFSET aaLevel
mov cx, 4000h
VPull_Loop: cmp BYTE PTR ds:[si], 0
je VPull_Next
dec BYTE PTR ds:[si]
jne VPull_Next
mov BYTE PTR ds:[si+(OFFSET aaColor-OFFSET aaLevel)], 60h
VPull_Next: inc si
dec cx
jne VPull_Loop
VPull_End: ret
VPull ENDP
;1) Drehung um die X-Achse mit Winkel a
;2) Drehung um die Y-Achse mit Winkel b
;
; ( 1 0 0 )
;A1 = ( 0 cos a -sin a )
; ( 0 sin a cos a )
;
; ( cos b sin b 0 )
;A2 = (-sin b cos b 0 )
; ( 0 0 1 )
;
; ( cos b sin b 0 ) ( x )
;A1*A2*v = (-cos a*sin b cos a*cos b -sin a ) * ( y ) ; z=0
; (-sin a*sin b sin a*cos b cos a ) ( z )
VRotate PROC NEAR
mov si, ds:[VAlpha]
mov di, ds:[VBeta]
mov bx, OFFSET VaEdge
mov bp, OFFSET Vx0
mov cx, 4
VRotate1: push cx
mov ax, ds:[di+SIN2COS] ; x*cos b
mov dx, ds:[bx]
imul dx
mov cx, dx
mov ax, ds:[di] ; +y*sin b
mov dx, ds:[bx+2]
imul dx
add cx, dx
mov ds:[bp], cx
mov ax, ds:[si+SIN2COS] ; x*cos a*sin b
mov dx, ds:[di]
imul dx
sal dx, 1
mov ax, ds:[bx]
imul dx
neg dx
mov cx, dx
mov ax, ds:[si+SIN2COS] ; +y*cos a*cos b
mov dx, ds:[di+SIN2COS]
imul dx
sal dx, 1
mov ax, ds:[bx+2]
imul dx
add cx, dx
mov ds:[bp+2], cx
mov ax, ds:[si] ; -x*sin a*sin b
mov dx, ds:[di]
imul dx
sal dx, 1
mov ax, ds:[bx]
imul dx
neg dx
mov cx, dx
mov ax, ds:[si] ; y*sin a*cos b
mov dx, ds:[di+SIN2COS]
imul dx
sal dx,1
mov ax, ds:[bx+2]
imul dx
add cx, dx
sar cx, 1
add ch, 60h
mov ax, ds:[bp] ; central projection in
imul cx ; x-direction
add dh, 20h
mov ds:[bp], dx
mov ax, ds:[bp+2] ; central-projection in
imul cx ; y-direction
add dh, 20h
mov ds:[bp+2], dx
add bx, 4
add bp, 4
pop cx
dec cx
je VRotate_End
jmp VRotate1
VRotate_End: ret
VRotate ENDP
VRun PROC NEAR
call VAdvance
call VBuild
call VShow
cmp ds:[Timer], 05feh
jna VRun
ret
VRun ENDP
VShow PROC NEAR
call Sync
push ds
mov ax, es
add ax, 04e3h
mov ds, ax
xor eax, eax
xor di, di
xor si, si
mov cx, ROWS
VShow_Copy2: push cx
mov cx, COLUMNS/2
VShow_Copy1: mov dl, ds:[si+1]
mov dh, dl
shl edx, 16
mov dl, ds:[si]
mov dh, dl
mov gs:[di], edx
mov ds:[si], ax
add di, 4
add si, 2
dec cx
jne VShow_Copy1
pop cx
add si, 96
add di, 192
dec cx
jne VShow_Copy2
pop ds
ret
VShow ENDP
VTaylor PROC NEAR ; get from one taylor-summand of
mul esi ; sin to another by multiplicating
shr eax, 15 ; it with x^2 and dividing it by
mul esi ; a suitable number
shr eax, 15
idiv ebx
ret
VTaylor ENDP
VWater PROC NEAR
mov ax, ds:[Timer]
and ax, 7fh
shr ax, 2
jc VWater_End
sub ax, 1fh
mov si, OFFSET aaLevel
mov cx, 4000h
VWater_Loop: cmp ds:[si], al
jnle VWater_Ok
inc BYTE PTR ds:[si]
mov BYTE PTR ds:[si+(OFFSET aaColor-OFFSET aaLevel)], 60h
VWater_Ok: inc si
dec cx
jne VWater_Loop
VWater_End: ret
VWater ENDP
VWave PROC NEAR
mov si, OFFSET aSin
mov bx, ds:[Timer]
mov bp, bx
sub bp, 300h
cmp bp, 7fh
jna VWave_Growth
mov bp, 7fh
VWave_Growth: shl bp, 9
shl bx, 8
neg bx
mov di, OFFSET aLevel
mov cx, 2*SIN_SIZE
VWave_Loop: and bx, 8*SIN_SIZE - 2
mov ax, ds:[si+bx]
add ah, 128
mul bp
shr bp, 1
sub dx, bp
add bp, bp
mov ds:[di], dx
add di, 2
add bx, 8
dec cx
jne VWave_Loop
xor bp, bp
mov di, OFFSET aaLevel
mov si, OFFSET aLevel
mov cx, 128*128
VWave_Level: mov bx, fs:[bp]
mov ax, ds:[si+bx]
sub dx, ax
shr dx, 5
add dl, 080h
shr dl, 2
add dl, 40h
mov ds:[OFFSET aaColor - OFFSET aaLevel + di], dl
mov dx, ax
sar ax, 11
mov ds:[di], al
inc di
add bp, 2
dec cx
jne VWave_Level
mov cx, 128
mov si, OFFSET aaColor
VWave_Adjust: mov al, ds:[si+1]
mov ds:[si], al
add si, 128
dec cx
jne VWave_Adjust
ret
VWave ENDP
INTRO_TEXT ENDS
END Main