home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Party 1994: Try This At Home
/
disk_image.bin
/
source
/
cloak
/
cloak.asm
next >
Wrap
Assembly Source File
|
1995-03-13
|
11KB
|
594 lines
; cloak
;
; (C)94 xToto/Valhalla
;
; first presented at the pc-party in herning/denmark
.model compact
.386
.stack 100h
Ysin_base = 8 ; sin-values in [0;pi/2[
Ysin_samples = 1 shl Ysin_base
Ywidth = 320 ; must be a multiple of 8
Yheight = 144 ; must be a multiple of 4
_data segment 'data'
Yvga_regs dw 003d4h
db 013h, Ywidth/8
db -1
dw -1
Ytimer dw 0
Yampl dw 0
Yviewport dw 0
Ymid db 80h
Ycmid dw 0
Ycdesc dw 0
include mapping.inc
Ydx0 dd ?
Ydy0 dd ?
Ydx1 dd ?
Ydy1 dd ?
Ydx2 dd ?
Ydy2 dd ?
Yp0 dd ?
Yp1 dd ?
Yp2 dd ?
Yt0 dd ?
Yt1 dd ?
Yt2 dd ?
Ylookup db 1000h dup (?) ; color lookup-table
Yoffs dw 100h dup (?) ; line offsets
Ycolors db 31h dup (?)
Ysin dw Ysin_samples dup (?)
Ycos dw Ysin_samples dup (?)
Ysin1 dw 2*Ysin_samples dup (?)
Ysin2 dw Ysin_samples dup (?)
_data ends
_sin segment 'bss'
dw 8000h dup (?)
_sin ends
_cloak segment 'bss'
dw 8000h dup (?)
_cloak ends
_text segment 'code'
; clear the keyboard-buffer and exit
; used registers: ax
Yclean_up:
mov ah, 01h ; clear key-buffer if needed
int 16h
jz Yclean_up1
mov ah, 00h
int 16h
jmp Yclean_up
Yclean_up1:
mov ax, 0003h ; restore text-mode
int 10h
mov ax, 4c00h ; quit program
int 21h
; calculate the next phase of a plasma-field
; used registers: all ?
Yframe:
mov cx, Yheight / 2
xor eax, eax
Yframe_loop2:
push cx
mov edx, Yp0
mov ebx, Yp1
mov esi, Yp2
shld ebp, esi, 16
shld esi, ebx, 16
shld ebx, edx, 16
mov cx, Ywidth / 8
Yframe_loop1:
add dx, 1234h
Yframe_1_1lo = $-2
adc ebx, 12345678h
Yframe_1_2lo_1hi = $-4
adc esi, 12345678h
Yframe_1_3lo_2hi = $-4
adc bp, 1234h
Yframe_1_3hi = $-2
and bx, 00ffh
and si, 00ffh
and bp, 00ffh
mov al, fs:[bx]
add al, fs:[si]
add al, fs:[bp]
add al, Ymid
mov es:[di], al
add dx, 1234h
Yframe_2_1lo = $-2
adc ebx, 12345678h
Yframe_2_2lo_1hi = $-4
adc esi, 12345678h
Yframe_2_3lo_2hi = $-4
adc bp, 1234h
Yframe_2_3hi = $-2
mov al, fs:[bx]
add al, fs:[si]
add al, fs:[bp]
add al, Ymid
mov es:[di+1], al
add dx, 1234h
Yframe_3_1lo = $-2
adc ebx, 12345678h
Yframe_3_2lo_1hi = $-4
adc esi, 12345678h
Yframe_3_3lo_2hi = $-4
adc bp, 1234h
Yframe_3_3hi = $-2
mov al, fs:[bx]
add al, fs:[si]
add al, fs:[bp]
add al, Ymid
mov es:[di+2], al
add dx, 1234h
Yframe_4_1lo = $-2
adc ebx, 12345678h
Yframe_4_2lo_1hi = $-4
adc esi, 12345678h
Yframe_4_3lo_2hi = $-4
adc bp, 1234h
Yframe_4_3hi = $-2
mov al, fs:[bx]
add al, fs:[si]
add al, fs:[bp]
add al, Ymid
mov es:[di+3], al
add di, 4
dec cx
jne Yframe_loop1
mov eax, Ydy0
add Yp0, eax
mov eax, Ydy1
add Yp1, eax
mov eax, Ydy2
add Yp2, eax
pop cx
dec cx
jne Yframe_loop2
ret
; do all needed initializations
; used regisers: all ?
Yinit:
mov ax, seg _data
mov ds, ax
mov ax, seg _cloak
mov es, ax
mov ax, seg _sin
mov fs, ax
mov ax, 0a000h
mov gs, ax
call Yinit_gfx
call Yinit_offset
call Yinit_lookup
call Yinit_pic
call Yinit_sin
ret
; initialize the graphics and colors
; used registers: all ?
Yinit_gfx:
mov ax, 0013h ; initiailze graphics-mode
int 10h
mov si, offset Yvga_regs ; rewrite some vga-regisers
Yinit_gfx_loop2:
lodsw
or ax, ax ; is it all done ?
js Yinit_gfx_ok
mov dx, ax
Yinit_gfx_loop1:
lodsb
or al, al ; use next port ?
js Yinit_gfx_loop2
out dx, al
inc dx
lodsb
out dx, al
dec dx
jmp Yinit_gfx_loop1
Yinit_gfx_ok:
ret
; initialize the color-loopup table
; used registers: all ?
Yinit_lookup:
mov di, offset Ylookup
xor bx, bx
Yinit_lookup1:
xor cx, cx
Yinit_lookup2:
mov ax, cx
mul bx
shr ax, 10
mov [di], al
inc di
inc cx
cmp cx, 100h
jne Yinit_lookup2
add bx, 011h
cmp bx, 0100h
jna Yinit_lookup1
ret
; initialize the offsets of the lines in memory
; used registers: all ?
Yinit_offset:
xor cx, cx
xor ax, ax
mov di, offset Yoffs
Yinit_offset1:
mov [di], ax
mov [di+2], ax
mov [di+4], ax
mov [di+6], ax
mov [di+8], ax
mov [di+10], ax
mov [di+12], ax
mov [di+14], ax
add di, 010h
add ax, Ywidth
add cx, 1 shl 3
cmp cx, 100h
jb Yinit_offset1
ret
; initialize the picture --- this is only a dummy routine
; used registers: all ?
Yinit_pic:
xor di, di
xor cx, Yheight
Yinit_pic1:
mov bx, Ywidth
Yinit_pic2:
mov fs:[di], cl
add fs:[di], bl
inc di
dec bx
jnz Yinit_pic2
dec cx
jnz Yinit_pic1
ret
; initialize a sin-lookup-table
; used registers: all ?
Yinit_sin:
xor di, di ; build a sin-lookup-table
xor cx, cx
xor bx, bx
Yinit_sin1:
mov ebx, 3373259426 ; <-- pi/2 * 65536 / 2
movzx eax, cx ; calculate x
mul ebx
shrd eax, edx, Ysin_base+1
mov esi, eax ; iteratively calculate the summands
mov ebp, eax ; +x
mov ebx, 6/2 ; -x^3 / 3!
call Ytaylor
sub ebp, eax
mov bl, 20/2 ; +x^5 / 5!
call Ytaylor
add ebp, eax
mov bl, 42/2 ; -x^7 / 7!
call Ytaylor
sub ebp, eax
mov bl, 72/2 ; +x^9 / 9!
call Ytaylor
add ebp, eax
mov bl, 110/2 ; -x^11 / 11!
call Ytaylor
sub ebp, eax
mov bl, 156/2 ; +x^13 / 13!
call Ytaylor
add ebp, eax
mov bl, 210/2/2 ; -x^15 / 15! , avoid 0x40000000
call Ytaylor
sub ebp, eax
shr ebp, 15
mov Ysin [di], bp ; sin(x)
mov Ysin2[di], bp ; = sin(2pi+x)
neg di
mov Ysin1[di], bp ; = sin(pi-x)
neg bp
mov Ysin2[di], bp ; =-sin(2pi-x)
neg di
mov Ysin1[di], bp ; =-sin(pi+x)
add di, 2
inc cx
cmp cx, Ysin_samples
jna Yinit_sin1
ret
; create a new sin-lookup-table with amplitude bx
; used registers: all ?
Ymodify_sin:
mov si, offset Ysin
xor di, di
mov cx, 100h
Ymodify_sin1:
mov ax, ds:[si]
add ax, 8000h
mov dx, bx
mul dx
mov fs:[di], dl
add si, (Ysin_samples / 256) * 8
inc di
dec cx
jne Ymodify_sin1
xor di, di
mov cx, 100h
Ymodify_sin2:
mov al,fs:[di]
mov fs:[di+100h], al
mov fs:[di+200h], al
mov fs:[di+300h], al
mov fs:[di-100h], al
mov fs:[di-200h], al
mov fs:[di-300h], al
inc di
dec cx
jnz Ymodify_sin2
ret
; check if a key was pressed
; used registers: ax
Ykey:
mov ah, 01h ; check keyboard-status
int 16h
ret
; modify the frame-routine (specify the field)
; used registers: eax
Ymodify_frame macro _dx0, _dx1, _dx2, _dy0, _dy1, _dy2, _t0, _t1, _t2, _dt0, _dt1, _dt2
mov Ydy0, _dy0
mov Ydy1, _dy1
mov Ydy2, _dy2
add _t0, _dt0
mov eax, _t0
mov Yt0, eax
mov Yp0, eax
add _t1, _dt1
mov eax, _t1
mov Yt1, eax
mov Yp1, eax
add _t2, _dt2
mov eax, _t2
mov Yt2, eax
mov Yp2, eax
mov word ptr cs:Yframe_1_1lo, _dx0 and 0ffffh
mov word ptr cs:Yframe_2_1lo, _dx0 and 0ffffh
mov word ptr cs:Yframe_3_1lo, _dx0 and 0ffffh
mov word ptr cs:Yframe_4_1lo, _dx0 and 0ffffh
mov dword ptr cs:Yframe_1_2lo_1hi, (_dx0 shr 16) or ((_dx1 and 65535) shl 16)
mov dword ptr cs:Yframe_2_2lo_1hi, (_dx0 shr 16) or ((_dx1 and 65535) shl 16)
mov dword ptr cs:Yframe_3_2lo_1hi, (_dx0 shr 16) or ((_dx1 and 65535) shl 16)
mov dword ptr cs:Yframe_4_2lo_1hi, (_dx0 shr 16) or ((_dx1 and 65535) shl 16)
mov dword ptr cs:Yframe_1_3lo_2hi, (_dx1 shr 16) or ((_dx2 and 65535) shl 16)
mov dword ptr cs:Yframe_2_3lo_2hi, (_dx1 shr 16) or ((_dx2 and 65535) shl 16)
mov dword ptr cs:Yframe_3_3lo_2hi, (_dx1 shr 16) or ((_dx2 and 65535) shl 16)
mov dword ptr cs:Yframe_4_3lo_2hi, (_dx1 shr 16) or ((_dx2 and 65535) shl 16)
mov word ptr cs:Yframe_1_3hi, _dx2 shr 16
mov word ptr cs:Yframe_2_3hi, _dx2 shr 16
mov word ptr cs:Yframe_3_3hi, _dx2 shr 16
mov word ptr cs:Yframe_4_3hi, _dx2 shr 16
endm
; main routine of the whole thing
; used registers: all ?
Ymain:
call Yinit
Ymain_loop:
call Yproceed
Ymodify_frame Ydx00 Ydx01 Ydx02 Ydy00 Ydy01 Ydy02 Yt00 Yt01 Yt02 Ydt00 Ydt01 Ydt02
mov bx, Yampl
call Ymodify_sin
mov di, 00000h
call Yframe
call Ydump
call Yproceed
Ymodify_frame Ydx10 Ydx11 Ydx12 Ydy10 Ydy11 Ydy12 Yt10 Yt11 Yt12 Ydt10 Ydt11 Ydt12
mov bx, Yampl
call Ymodify_sin
mov di, 04000h
call Yframe
call Ydump
call Yproceed
Ymodify_frame Ydx20 Ydx21 Ydx22 Ydy20 Ydy21 Ydy22 Yt20 Yt21 Yt22 Ydt20 Ydt21 Ydt22
mov bx, Yampl
call Ymodify_sin
mov di, 08000h
call Yframe
call Ydump
call Ykey
jz Ymain_loop
call Yclean_up
; draw the next frame to the video-ram
; used registers: all ?
Ydump:
xor ebx, ebx
mov bp, Ywidth/2
xor si, si
xor di, di
Ydump_loop:
xor bx, bx
mov bl, es:[si]
mov bx, Yoffs[2*ebx]
mov ax, es:[si+4000h-1]
shr ax, 11
add bx, ax
mov dl, es:[si+8000h]
and dl, 0f0h
mov dh, dl
mov ax, fs:[di+bx+10h]
; mov ax, 0707h
or ax, dx
mov gs:[di], ax
mov ax, fs:[di+bx+Ywidth+10h]
; mov ax, 0707h
or ax, dx
mov gs:[di+Ywidth], ax
add di, 2
inc si
dec bp
jnz Ydump_noskip
mov bp, Ywidth/2
add di, Ywidth
Ydump_noskip:
cmp si, (Ywidth/2)*(Yheight/2)
jb Ydump_loop
ret
; called every frame for time-dependant stuff
; used registers: ax
Yproceed:
inc Ytimer
cmp Ytimer, 0aah
jae Yproceed1
mov ax, Ytimer
shr ax, 1
mov Yampl, ax
Yproceed1:
cmp Ytimer, 356h
jb Yproceed2
mov ax, 400h
sub ax, Ytimer
shr ax, 1
mov Yampl, ax
Yproceed2:
cmp Ytimer, 400h
jb Yproceed3
jmp Yclean_up
Yproceed3:
mov ax, Ytimer
shr ax, 2
mov dx, ax
sub ax, 0ffh
neg ax
mov Ycmid, ax
cmp dx, 080h
jb Yproceed4
sub dx, 100h
neg dx
Yproceed4:
shr dx, 3
jz Yproceed5
dec dx
Yproceed5:
mov Ycdesc, dx
mov ax, 0ffh
sub ax, Yampl
sub ax, Yampl
sub ax, Yampl
shr ax, 1
mov Ymid, al
call Ypalette
ret
; build the new palette
; used registers: all ?
Ypalette:
mov ax, Ycmid
mov bp, ax
mov bx, ax
mov dx, Ycdesc
shl dx, 3
sub ax, dx
add bp, dx
shr dx, 3
mov si, offset Ycolors
mov cx, 10h
Ypalette1:
mov [si], ax
mov [si+1], bx
mov [si+2], bp
add si, 3
add ax, dx
sub bp, dx
dec cx
jnz Ypalette1
mov dx, 03c8h
xor al, al
out dx, al
inc dx
mov di, offset Ycolors
xor bx, bx
mov cx, 10h
Ypalette2:
push cx
mov si, offset Ylookup
mov cx, 10h
Ypalette3:
mov bl, ds:[di]
mov al, [si+bx]
out dx, al
mov bl, ds:[di+1]
mov al, [si+bx]
out dx, al
mov bl, ds:[di+2]
mov al, [si+bx]
out dx, al
add si, 100h
dec cx
jnz Ypalette3
add di, 3
pop cx
dec cx
jnz Ypalette2
ret
; auxiliary-routine for the sin-calculation
; used registers: eax, ebx, edx, esi
Ytaylor:
mul esi ; calculate the next summand
shrd eax, edx, 30
mul esi
shrd eax, edx, 31
xor edx, edx
div ebx
ret
_text ends
end Ymain