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
w3cw3c
automatyka przemysłowa