Plazma
-- Sebastian Pawlak, 1998.
Przedstawiony kod generuje prosty efekt plazmy liczonej w czasie
rzeczywistym.
Program ten napisałem z użyciem opkodów koprocesora zgodnego z 80387.
Analiza kodu pozwala zapoznać się z programowaniem z użyciem FPU
oraz z zasadami optymalizacji.
Jako podręcznik do kodowania FPU, polecam "Procesory Pentium"
Michaela L. Schmita.
; ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ Plasma Effect in 256 bytes ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛
;
; code: TrIx
; (C)1998
Code SEGMENT
Assume Cs:Code
.386
.387
org 100h
Start:
jmp Main
;°°°°°°°°°°°°°°°° Stale i dane °°°°°°°°°°°°°°°°
Sin equ 100h+500 ; adres tablicy Sinusow
Cos equ 100h+500+256*2 ; adres tablicy Cosinusow
Pal equ 100h+500+256*4 ; adres palety kolorow
Pal_ equ 100h+500+256*4+3*128 ; adres palety kolorow od srodka
p255 dw 255 ; mnoznik dla generatora Sinusow
p128 dw 128 ; mnoznik dla generatora Cosinusow
radius dd 0.024639942 ; stala dla gen. Sin/Cos : 0.2463..=2*PI/255
;˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛ Poczatek programu ˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛˛
Main:
;°°°°°°°°°°°°°°°° Generator Sin/Cos °°°°°°°°°°°°°°°°
mov si,Sin
mov di,Cos
fldz ; zero na stos koprocesora
mov cx,256
next_SinCos:
fld radius ; radius {0.2463..} na stos koprocesora
fmul st,st(1) ; mnozenie st i st(1), wynik na stos
fsincos ; Sin i Cos, dla kata otrzymanego wyzej, na stos kopr.
fimul p128 ; mnozenie wartosci Cos przez stala p128 {128}
frndint ; zaokraglenie wyniku powyzszego mnozenia
fistp word ptr [di] ; zapamietanie wyniku w tablicy
fimul p255 ; mnozenie wartosci Sin przez stala p255 {255}
frndint ; zaokraglenie wyniku powyzszego mnozenia
fistp word ptr [si] ; zapamietanie wyniku w tablicy
fld1 ; zwiekszenie wartosci
fadd ; przechowywanej na stosie kopr. o 1
inc si
inc si
inc di
inc di
loop next_SinCos
;°°°°°°°°°°°°°°°° Generator palety kolorow °°°°°°°°°°°°°°°°
mov ax,13h
int 10h
mov si,Pal
mov di,Pal_
mov bx,127 ; bl=127, bh=0
next_color:
;°°° Red °°°
mov ax,bx
shr al,2
mov [si],al
inc si
shr ah,2 ;---
mov [di],ah
inc di
;°°° Green °°°
shr al,1
mov [si],al
inc si
shr ah,1 ;---
mov [di],ah
inc di
;°°° Blue °°°
; shr ah,1
mov [si],ah
inc si
; shr al,1 ;---
mov [di],al
inc di
inc bh
dec bl
jns next_color ; skok wtedy gdy bl > 0
;°°° inicjalizacja nowej palety °°°
mov dx,3C8h
out dx,al ; al=zero
mov si,Pal
mov cx,768
inc dx
rep outsb
;°°°°°°°°°°°°°°°° GLOWNA PETLA PROGRAMU °°°°°°°°°°°°°°°°
push 0a000h
pop es
MAIN_LOOP:
mov di,0 ; zerowanie offsetu ekranowego
;°°° wspolrzedna Y °°°
mov bx,0
next_Y:
;°°° wspolrzedna X °°°
mov cx,0
next_X:
mov al,dl
add ax,cx
and ax,0FFh
mov si,Cos
add si,ax
add si,ax
mov bp,[si]
mov ah,0
mov al,dh
add ax,bx
and ax,0FFh
mov si,Sin
add si,ax
add si,ax
mov ax,[si]
add ax,bp
shl cx,2
add ax,cx
shr cx,2
mov es:di,al ; wyswietlanie punktu na ekranie
inc di
inc cx
cmp cx,320
jne next_X
inc bx
cmp bx,200
jne next_Y
sub dl,3
add dh,3
mov ah,11h ; sprawdzanie czy nie zostal nacisniety jakis klawisz ...
int 16h
je MAIN_LOOP ; ... jesli nie to glowna petla powtarza sie
;°°°°°°°°°°°°°°°° Koniec °°°°°°°°°°°°°°°°
mov ax,03h
int 10h
mov ah,09h
mov dx,offset Info
int 21h
mov ah,4ch
int 21h
Info DB 'TrIx$'
ends
end Start





