/* NOTE: This is just a complition of all the source code files. This file
   can not be compiled. Use the original files instead! */

;=============================================================================
; flag.asm - Runtime Flag Demostration.
;                                                   File created: 10-22-93
; Copyright (C) 1993, Carlos Hasan                 Last modified: 10-22-93
;
; Description:
;   This file implements a runtime flag movement using plasma like
;   sinus overlapping waves in the VGA 320x200x256 graphics mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;=============================================================================

		.model  small,pascal
		.286

		dosseg                          ; used to link like
		.stack  1024                    ; an standalone program.

		global  FlagDemo:proc

;======================= Demo equates and data ===============================

TIMEOUT         equ     70 * 8                  ; at least 8 secs.
BMPWIDTH        equ     160                     ; bitmap dimens.
BMPHEIGHT       equ     96
MAXWIDTH        equ     320                     ; screen dimens.
MAXHEIGHT       equ     200
XOFS            equ     80                      ; flag upper left
YOFS            equ     30                      ; corner coordinates.

		.data

; flag bitmap, palette and sinus wave tables.
; The bitmap is about 15K, but because it's highly compressed using
; any exepacker, it was included in the data segment avoiding the
; extra segment needed in the demo algorithms.

		include flagbmp.inc 

HWavPos         db      ?                       ; wave horiz and vert
VWavPos         db      ?                       ; positions.

FadePalette     db      768 dup (?)             ; faded palette.
Fade            db      ?                       ; fade level.
Esckey          db      ?                       ; true if key pressed.
Timer           dw      ?                       ; timer counter.

;======================= Demo routines =======================================

		.code

;-----------------------------------------------------------------------------
; WaitVRT - Waits the Vertical Retrace.
;-----------------------------------------------------------------------------

WaitVRT         proc near

		mov     dx,3DAh
WaitVR1:        in      al,dx
		test    al,8
		jne     WaitVR1
WaitVR2:        in      al,dx
		test    al,8
		je      WaitVR2
		ret

WaitVRT         endp

;-----------------------------------------------------------------------------
; SetPalette - set the CX entries of the VGA color palette.
; In:
;   DS:SI - Palette structure address.
;   CX    - Number of colors components.
;-----------------------------------------------------------------------------

SetPalette      proc near

		call    WaitVRT
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		inc     dx
		rep     outsb
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; PutFlag - Writes the next Flag Frame to the Screen.
;-----------------------------------------------------------------------------

PutFlag         proc near

		mov     ax,0A000h
		mov     es,ax
		add     [HWavPos],4             ; Incr Wave Positions.
		add     [VWavPos],7
		mov     dh,[HWavPos]            ; k = hwavpos.
		mov     di,MAXWIDTH*YOFS+XOFS   ; p = screen offset.
		lea     si,[Piccy]              ; q = piccy offset.
		mov     cx,BMPWIDTH-16          ; for col=0 to W-16 do
		xor     bh,bh
ColLoop:        push    cx
		push    si
		push    di
		mov     bl,dh
		mov     dl,[VWave+bx]           ; x = vwave[k]
		mov     al,[HWave+bx]           ; h = (x+hwave[k])/2
		add     al,dl
		rcr     al,1
		mov     ah,BMPWIDTH             ; q= col+160*h
		mul     ah
		add     si,ax
		mov     ah,[VWavPos]            ; l = vwavpos
		mov     cx,BMPHEIGHT-16         ; for row=0 to H-16 do
RowLoop:        mov     bl,ah
		mov     bl,[VWave+bx]           ; v = (x+vwave[l])/2
		add     bl,dl
		rcr     bl,1
		mov     al,[si+bx]              ; al = pic[si+v]+vwave[k+v]
		add     bl,dh
		mov     bl,[VWave+bx]
		xor     bl,0Fh
		add     al,bl
		mov     es:[di],al              ; put pixel.
		add     di,MAXWIDTH             ; p= p+320
		add     si,BMPWIDTH             ; q= q+160
		inc     ah                      ; l= l+1
		loop    RowLoop
		pop     di
		pop     si
		pop     cx
		inc     dh                      ; k=k+1
		inc     si                      ; q=q+1
		inc     di                      ; p=p+1
		test    di,1                    ; if odd(p) p=p+320
		jne     ColBrk
		add     di,MAXWIDTH
ColBrk:         loop    ColLoop                 ; next col.
		ret

PutFlag         endp

;-----------------------------------------------------------------------------
; FlagDemo - Performs the demonstration.
; In:
;   DS - Data segment.
;-----------------------------------------------------------------------------

FlagDemo        proc

		pusha
		push    ds
		push    es

		mov     ax,0013h                ; set 320x200x256 mode.
		int     10h

		mov     [Fade],0                ; setup variables.
		mov     [EscKey],0
		mov     [Timer],0

		mov     [HWavPos],0
		mov     [VWavPos],0

FlagLoop:       cmp     [EscKey],0              ; change fade level.
		jne     FadeOut
FadeIn:         mov     bl,[Fade]
		cmp     bl,64
		jae     SkipFade
		inc     [Fade]
		jmp     FadeInOut
FadeOut:        mov     bl,[Fade]
		cmp     bl,0
		jbe     FadeInOut
		dec     [Fade]

FadeInOut:      lea     si,[Palette]            ; set faded palette.
		lea     di,[FadePalette]
		mov     cx,3*16*4
		mov     ax,ds
		mov     es,ax
		cld
FadeLoop:       lodsb
		mul     bl
		shr     ax,6
		stosb
		loop    FadeLoop

DoFade:         lea     si,[FadePalette]        ; ensures thats always
		mov     cx,3*16*4               ; waits the VR per frame.
		call    SetPalette
		jmp     DoFlag

SkipFade:       call    WaitVRT

DoFlag:         call    PutFlag                 ; put the flag.

		mov     ah,1                    ; if any key pressed,
		int     16h
		jz      CheckTimer
		mov     ah,0
		int     16h
		jmp     BeginFadeOut

CheckTimer:     inc     [Timer]                 ; or timeout,
		cmp     [Timer],TIMEOUT
		jb      CheckExit

BeginFadeOut:   inc     [EscKey]                ; then fade-out and exit.

CheckExit:      cmp     [Fade],0
		je      FlagExit
		jmp     FlagLoop

FlagExit:       mov     ax,0003h
		int     10h

		pop     es
		pop     ds
		popa
		ret

FlagDemo        endp


;-----------------------------------------------------------------------------
; Start - Startup code called from DOS.
; In:
;   DS - Program Segment Prefix.
;-----------------------------------------------------------------------------

Start           proc

		mov     ax,@Data
		mov     ds,ax
		call    FlagDemo
		mov     ax,4C00h
		int     21h

Start           endp

		end     Start
;=============================================================================
; mandel.asm - Mandelbrot Set calculation Routines.
;                                                    File created:  9-22-93
; Copyright (C) 1993, Carlos Hasan                  Last modified: 10-11-93
;
; Description:
;  This file implements the Mandelbrot Set fractal using a fast algorithm
;  based on the Fracint's Boundary trace method. The drawing is optimized
;  for using with VGA 320x200x256 graphics mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 386 or later microprocessor.
;=============================================================================

		.model  small,pascal
		.386

		global  DrawMandel:proc

;======================= Mandelbrot Routine ==================================

;-----------------------------------------------------------------------------
; Equates for Mandelbrot Set calculation.
;-----------------------------------------------------------------------------

MAXITER         equ     150                     ; max iterations
FUDGE           equ     24                      ; fudge factor
BAILOUT         equ     4 shl FUDGE             ; bait out
PERIODMASK      equ     0FFFF0000h              ; periodicy mask

;-----------------------------------------------------------------------------
; Miscellaneus Data used for calculation.
;-----------------------------------------------------------------------------

		.data

SavedAnd        dw      ?
SavedIncr       dw      ?
SavedMask       dd      ?
OldIter         dw      ?
LinX            dd      ?
LinY            dd      ?
SavedX          dd      ?
SavedY          dd      ?

;-----------------------------------------------------------------------------
; CalcMand - Main Mandelbrot Set calculation routine.
; In:
;   ESI  - real part of the initial complex value.
;   EDI  - imaginary part of the initial complex value.
; Out:
;   AL   - Mandelbrot level.
; Modified:
;   EAX, EBX, ECX, EDX, ESI, EDI, Flags.
;-----------------------------------------------------------------------------

		.code

CalcMand        proc near

		mov     [SavedAnd],1            ; init periodicy check.
		mov     [SavedIncr],1
		mov     [SavedMask],1
		mov     [SavedX],0FFFFFFFFh     ; values impossibles
		mov     [SavedY],0FFFFFFFFh     ; for x and y.

		mov     [LinX],esi              ; linx = real
		mov     [LinY],edi              ; liny = imag

		xor     esi,esi                 ; x = 0
		xor     edi,edi                 ; y = 0

		mov     cx,MAXITER              ; iter = maxiter

MandLoop:       mov     eax,esi                 ; ebx = x*x
		imul    esi
		shrd    eax,edx,FUDGE
		mov     ebx,eax

		mov     eax,edi                 ; ebx = y*y
		imul    edi
		shrd    eax,edx,FUDGE

		mov     edx,ebx                 ; edx = x*x + y*y
		add     edx,eax
		sub     ebx,eax                 ; ebx = x*x - y*y

		cmp     edx,BAILOUT             ; x*x + y*y > bailout?
		jge     MandBreak               ; break.

		mov     eax,edi                 ; y = 2*x*y + liny
		imul    esi
		shrd    eax,edx,FUDGE-1
		add     eax,[LinY]
		mov     edi,eax

		add     ebx,[LinX]              ; x = x*x - y*y + linx
		mov     esi,ebx

		cmp     [OldIter],cx            ; check periodicity.
		jle     MandContinue

		mov     eax,esi
		xor     eax,[SavedX]
		test    eax,PERIODMASK
		jne     CheckSave
		mov     eax,edi
		xor     eax,[SavedY]
		test    eax,PERIODMASK
		jne     CheckSave
		xor     cx,cx
		jmp     MandBreak

CheckSave:      test    cx,[SavedAnd]
		jne     MandContinue
		mov     [SavedX],esi
		mov     [SavedY],edi
		dec     [SavedIncr]
		jne     MandContinue
		stc
		rcl     [SavedAnd],1
		mov     [SavedIncr],4

MandContinue:   dec     cx
		jne     MandLoop

MandBreak:      mov     ax,cx
		mov     bx,cx
		sub     bx,10
		test    cx,cx
		je      SetOldIter
		mov     bx,MAXITER
SetOldIter:     mov     [OldIter],bx
		ret

CalcMand        endp


;=================== Boundary Trace Method (BTM) =============================

;-----------------------------------------------------------------------------
; Equates for BTM into a 320x200x256 virtual screen.
;-----------------------------------------------------------------------------

MAXWIDTH        equ     320                     ; Virtual screen dimensions.
MAXHEIGHT       equ     200
XSTART          equ     0                       ; Virtual screen drawing
XSTOP           equ     319                     ; window coordinates.
YSTART          equ     0
YSTOP           equ     199
NORTH           equ     0                       ; Used for BTM algorithm.
EAST            equ     1
SOUTH           equ     2
WEST            equ     3
MAXINT          equ     7FFFh

;-----------------------------------------------------------------------------
; Data used for BTM during plotting.
;-----------------------------------------------------------------------------

		.data

LeftX           dw      MAXHEIGHT dup (?)       ; array of left and right
RightX          dw      MAXHEIGHT dup (?)       ; limits for poly filling.
ComplexX        dd      MAXWIDTH  dup (?)       ; translate screen coords
ComplexY        dd      MAXHEIGHT dup (?)       ; to complex coords.
FirstX          dw      ?                       ; temporary variables used
FirstY          dw      ?                       ; for BTM algorithm.
Iters           dw      ?
Color           db      ?
Dir             db      ?

;-----------------------------------------------------------------------------
; GetPixel - get the pixel color at specified location.
; In:
;   ES      - Virtual screen segment.
;   (SI,DI) - Pixel position.
; Out:
;   AL      - Pixel color.
; Modified:
;   BX, Flags.
;-----------------------------------------------------------------------------

		.code

GetPixel        macro

		mov     bx,di
		imul    bx,MAXWIDTH
		add     bx,si
		mov     al,es:[bx]

		endm

;-----------------------------------------------------------------------------
; PutPixel - put the pixel color at specified location.
; In:
;   ES      - Virtual screen segment.
;   (SI,DI) - Pixel position.
;   AL      - Pixel color.
; Modified:
;   BX, Flags.
;-----------------------------------------------------------------------------

PutPixel        macro

		mov     bx,di
		imul    bx,MAXWIDTH
		add     bx,si
		mov     es:[bx],al

		endm

;-----------------------------------------------------------------------------
; GetColor - get the pixel color using the MandelBrot Set routine or
;   the virtual screen if already painted.
; In:
;   ES       - Virtual screen segment.
;   (SI,DI)  - Pixel position.
; Out:
;   AL       - Pixel color.
; Modified:
;   EAX, EBX, ECX, EDX, Flags.
;-----------------------------------------------------------------------------

GetColor        proc near

		GetPixel
		test    al,al
		jne     ColorNonZero
		push    si
		push    di
		shl     si,2
		shl     di,2
		mov     esi,[ComplexX+si]
		mov     edi,[ComplexY+di]
		call    CalcMand
		pop     di
		pop     si
		inc     al
		PutPixel                ; don't destroy AL.
ColorNonZero:   ret

GetColor        endp

;-----------------------------------------------------------------------------
; BoundTrace - Trace a boundary and fill it.
; In:
;   ES      - Virtual screen segment.
;   (SI,DI) - starting point inside of the boundary.
; Modified:
;   EAX, EBX, ECX, EDX, Flags.
;-----------------------------------------------------------------------------

BoundTrace      proc near

		mov     [FirstX],si
		mov     [FirstY],di
		call    GetColor
		mov     [Color],al
		mov     [Dir],EAST
		mov     [Iters],0

BoundLoop:      mov     bx,di
		shl     bx,1
		cmp     si,[LeftX+bx]
		jge     NotLess
		mov     [LeftX+bx],si
NotLess:        cmp     si,[RightX+bx]
		jle     NotGreat
		mov     [RightX+bx],si
NotGreat:       mov     al,[Dir]
		cmp     al,NORTH
		je      GoNorth
		cmp     al,EAST
		je      GoEast
		cmp     al,SOUTH
		je      GoSouth
		cmp     al,WEST
		je      GoWest

GoNorth:        cmp     di,[FirstY]
		jle     SetEast
		dec     di
		call    GetColor
		inc     di
		cmp     al,[Color]
		jne     SetEast
		dec     di
		cmp     si,XSTART
		jle     BoundContinue
		dec     si
		call    GetColor
		inc     si
		cmp     al,[Color]
		jne     BoundContinue
		dec     si
		jmp     SetWest

GoEast:         cmp     si,XSTOP
		jge     SetSouth
		inc     si
		call    GetColor
		dec     si
		cmp     al,[Color]
		jne     SetSouth
		inc     si
		cmp     di,[FirstY]
		jle     BoundContinue
		dec     di
		call    GetColor
		inc     di
		cmp     al,[Color]
		jne     BoundContinue
		dec     di
		jmp     SetNorth

GoSouth:        cmp     di,YSTOP
		jge     SetWest
		inc     di
		call    GetColor
		dec     di
		cmp     al,[Color]
		jne     SetWest
		inc     di
		cmp     si,XSTOP
		jge     BoundContinue
		inc     si
		call    GetColor
		dec     si
		cmp     al,[Color]
		jne     BoundContinue
		inc     si
		jmp     SetEast

GoWest:         cmp     si,XSTART
		jle     SetNorth
		dec     si
		call    GetColor
		inc     si
		cmp     al,[Color]
		jne     SetNorth
		dec     si
		cmp     di,YSTOP
		jge     BoundContinue
		inc     di
		call    GetColor
		dec     di
		cmp     al,[Color]
		jne     BoundContinue
		inc     di
		jmp     SetSouth

SetNorth:       mov     [Dir],NORTH
		jmp     BoundContinue

SetEast:        mov     [Dir],EAST
		jmp     BoundContinue

SetSouth:       mov     [Dir],SOUTH
		jmp     BoundContinue

SetWest:        mov     [Dir],WEST

BoundContinue:  inc     [Iters]
		cmp     si,[FirstX]
		jne     BoundLoop
		cmp     di,[FirstY]
		jne     BoundLoop

		cmp     [Iters],4
		jl      BoundExit

		mov     si,[FirstY]
		cld
BoundForY:      mov     bx,si
		shl     bx,1
		mov     ax,[LeftX+bx]
		mov     dx,[RightX+bx]
		mov     [LeftX+bx],+MAXINT
		mov     [RightX+bx],-MAXINT
		cmp     ax,dx
		jg      BoundExit
		mov     cx,dx
		sub     cx,ax
		inc     cx
		mov     di,si
		imul    di,MAXWIDTH
		add     di,ax
		mov     al,[Color]
ScanColor:      repne   scasb
		jne     BoundNextY
		jcxz    BoundNextY
FillBlank:      mov     ah,es:[di]
		test    ah,ah
		jne     ScanColor
		mov     es:[di],al
		inc     di
		dec     cx
		jne     FillBlank
BoundNextY:     inc     si
		cmp     si,YSTOP
		jle     BoundForY

BoundExit:      mov     si,[FirstX]
		mov     di,[FirstY]
		ret

BoundTrace      endp

;-----------------------------------------------------------------------------
; DrawMandel - Draw the Mandelbrot Set into a virtual 320x200x256 screen.
; In:
;   (PosX,PosX)      - top left corner complex number.
;   (DeltaX,DeltaY)  - complex windows extends.
;   ScreenSeg        - Virtual screen segment.
;-----------------------------------------------------------------------------

DrawMandel      proc    PosX:dword,PosY:dword, \
			DeltaX:dword,DeltaY:dword, ScreenSeg:word

		mov     ax,ds
		mov     es,ax
		cld

		mov     cx,MAXHEIGHT
		lea     di,[LeftX]
		mov     ax,+MAXINT
		rep     stosw

		mov     cx,MAXHEIGHT
		lea     di,[RightX]
		mov     ax,-MAXINT
		rep     stosw

		mov     ecx,XSTOP-XSTART
		mov     eax,[DeltaX]
		cdq
		div     ecx
		inc     cx
		mov     edx,eax
		add     eax,[PosX]
		add     eax,[PosX]
		sar     eax,1
		lea     di,[ComplexX]
MakeX:          stosd
		add     eax,edx
		loop    MakeX

		mov     ecx,YSTOP-YSTART
		mov     eax,[DeltaY]
		cdq
		div     ecx
		inc     cx
		mov     edx,eax
		add     eax,[PosY]
		add     eax,[PosY]
		sar     eax,1
		lea     di,[ComplexY]
MakeY:          stosd
		add     eax,edx
		loop    MakeY

		mov     ax,[ScreenSeg]
		mov     es,ax
		mov     cx,MAXWIDTH * MAXHEIGHT
		xor     di,di
		xor     ax,ax
		rep     stosb

		mov     di,YSTART
ForY:           mov     si,XSTART
ForX:           GetPixel
		test    al,al
		jne     NextX
		call    BoundTrace
NextX:          inc     si
		cmp     si,XSTOP
		jle     ForX
NextY:          inc     di
		cmp     di,YSTOP
		jle     ForY
		ret

DrawMandel      endp

		end
;=============================================================================
; zoom.asm - Mandelbrot Set Zoom Demostration.
;                                                    File created: 10-11-93
; Copyright (C) 1993, Carlos Hasan                  Last modified: 11-21-93
;
; Description:
;  This file implements the Runtime MandelZoom demostration. Needs the
;  Mandelbrot Set calculation routines and the zoom-in path include file.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 386 and the VGA graphics card.
;
; Modifications:
;  10/22/93 - Startup Code.
;  11/21/93 - Now this thing Shows the Frame Creation.
;=============================================================================

		.model  small,pascal
		.386

		dosseg                          ; used to link like
		.stack  1024                    ; an standalone program.

		global  MandelZoom:proc
		global  DrawMandel:proc         ; in MANDEL.ASM

;===================== Demo Equates ==========================================

MAXWIDTH        equ     320                     ; VGA Screen Dimensions.
MAXHEIGHT       equ     200

;===================== Demo Data =============================================

		.data

		include ZoomPath.Inc            ; Zoom-In Information.
						; and Color Palette.

GridX           dw      WINSIZEX dup (?)        ; Used to compute the
GridY           dw      WINSIZEY dup (?)        ; Zoom-In Window.

;===================== Demo Routines =========================================

		.code

;-----------------------------------------------------------------------------
; WaitVRT - Waits the next VGA Vertical Retrace Period.
;-----------------------------------------------------------------------------

WaitVRT         proc near

		mov     dx,3DAh
WaitVRT1:       in      al,dx
		test    al,8
		jz      WaitVRT1
WaitVRT2:       in      al,dx
		test    al,8
		jnz     WaitVRT2
		ret

WaitVRT         endp

;-----------------------------------------------------------------------------
; BlackPalette - Set a Black Palette.
;-----------------------------------------------------------------------------

BlackPalette    proc near

		call    WaitVRT
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		inc     dx
		mov     cx,768
BlackLoop:      out     dx,al
		loop    BlackLoop
		ret

BlackPalette    endp


;-----------------------------------------------------------------------------
; SetPalette - Sets the Color Palette.
;-----------------------------------------------------------------------------

SetPalette      proc near

		call    WaitVRT
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		inc     dx
		lea     si,[Palette]
		mov     cx,768
		rep     outsb
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; FadeInPalette - Fade-In the palette.
;-----------------------------------------------------------------------------

FadeInPalette   proc near

		xor     bx,bx
FadeInLoop:     lea     si,[Palette]
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		mov     cx,768
		call    WaitVRT
		mov     dx,3C9h
FadeIn:         lodsb
		mul     bl
		mov     al,ah
		out     dx,al
		loop    FadeIn
		add     bl,4
		jnc     FadeInLoop
		ret

FadeInPalette   endp


;-----------------------------------------------------------------------------
; FadeOutPalette - Fade-Out the palette.
;-----------------------------------------------------------------------------

FadeOutPalette  proc near

		mov     bl,252
FadeOutLoop:    call    WaitVRT
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		inc     dx
		lea     si,[Palette]
		mov     cx,768
FadeOut:        lodsb
		mul     bl
		mov     al,ah
		out     dx,al
		loop    FadeOut
		sub     bl,4
		jnc     FadeOutLoop
		ret

FadeOutPalette  endp


;-----------------------------------------------------------------------------
; ClearScreen - Clears the Video Screen using a Spray-like effect.
;-----------------------------------------------------------------------------

ClearScreen     proc near

		push    ds
		push    es

		mov     ax,0A000h
		mov     es,ax

		xor     cx,cx
SprayLoop:      push    cx
		xor     bx,bx
SprayLine:      push    bx
		mov     ah,cs:[RandTable+bx]
		mov     bx,cx
		mov     al,cs:[RandTable+bx]
		mov     bx,ax
		mov     di,ax
		xor     al,al
		mov     es:[di],al
		pop     bx
		inc     cl
		inc     bl
		jne     SprayLine
		pop     cx
		inc     cl
		jne     SprayLoop

		pop     es
		pop     ds
		ret

RandTable label byte
      db   83,   8,  18, 177,  13, 241, 149, 157
      db   75, 248, 254,  23,  16,  66, 207,  31
      db  211, 183,  80, 242, 218,  27,  15, 128
      db   94,  98,   4,  36, 139, 110,  85, 230
      db  212,  26,  12, 249, 169, 233, 200, 150
      db   95, 114, 130, 167, 202, 187,  76, 145
      db   62, 117, 115, 190, 209,  42, 185, 224
      db  129, 104, 108, 192, 174, 137,  44,  41
      db  141,  53, 179,  81, 181,  57, 147, 210
      db   50, 134, 156, 125, 133, 126, 106, 162
      db   20,  59,  84,   0, 151, 143, 101, 215
      db   68, 246, 189, 197,  99, 213, 112, 144
      db   28, 235, 240,  90, 154,  56, 138, 165
      db   19, 166, 159,  92, 127, 208, 105, 118
      db  119, 153, 191, 184,  87,  70,   9, 164
      db   60, 252,  96,   3, 171,  38, 136,  14
      db    7, 160,  71, 146, 102, 229, 227,  43
      db  221, 182, 217,  30, 131, 219,  61, 180
      db  195, 245, 109, 203,  24,  49, 170, 247
      db   46, 148, 122, 250, 173, 107, 255, 194
      db    6,  37,  93,  22, 168,  97, 193,   5
      db   51, 223, 116,  86,   1,  89, 121, 243
      db  140, 220,  39, 222,  65,  55,  17,  54
      db  175, 206, 214, 155, 142, 163,  25, 188
      db  178,  11, 204, 135, 201, 238,  79, 132
      db  198,  40,  21,  45, 237, 253, 152,  74
      db   32, 111,  52,  47, 236,   2, 176, 239
      db  234,  58, 100,  91, 172,  73,  82, 205
      db   34,  88,  78, 231, 232, 225,  48, 251
      db   67, 123, 244,  29, 216,  64, 196,  69
      db  199,  33,  72,  35,  10,  63, 161, 228
      db  113, 158, 120, 103, 124, 186, 226,  77

ClearScreen   endp


;-----------------------------------------------------------------------------
; ZoomBox - Draws the Zoom Window using the precalculated Mandelbrot
;  pictures and coordinates in the ZoomPath include file.
;-----------------------------------------------------------------------------

ZoomBox         proc near XStart:word,YStart:word,XStop:word,YStop:word, \
		     PicSeg:word

		mov     si,[XStart]             ; compute the GridX array.
		mov     di,[XStop]
		lea     bx,[GridX]
		mov     cx,WINSIZEX
		mov     ax,di
		sub     ax,si
		cwd
		div     cx
		xchg    si,ax
		mov     di,dx
		mov     dx,cx
		shr     dx,1
		neg     dx
MakeGridX:      mov     [bx],ax
		add     ax,si
		add     dx,di
		jl      SkipX
		sub     dx,WINSIZEX
		inc     ax
SkipX:          add     bx,2
		loop    MakeGridX

		mov     si,[YStart]             ; compute the GridY array.
		mov     di,[YStop]
		lea     bx,[GridY]
		mov     cx,WINSIZEY
		mov     ax,di
		sub     ax,si
		cwd
		div     cx
		xchg    si,ax
		mov     di,dx
		mov     dx,cx
		shr     dx,1
		neg     dx
MakeGridY:      mov     [bx],ax
		add     ax,si
		add     dx,di
		jl      SkipY
		sub     dx,WINSIZEY
		inc     ax
SkipY:          add     bx,2
		loop    MakeGridY

		mov     dx,[PicSeg]
		mov     cx,ds
		mov     ax,0A000h
		mov     es,ax
		mov     di,WINPOSX+320*WINPOSY
		cld


		xor     bx,bx
ZoomLoopY:      push    bx
		mov     ax,[GridY+bx]
		imul    ax,ax,MAXWIDTH
		xor     bx,bx
ZoomLoopX:      mov     si,ax
		add     si,[GridX+bx]
		mov     ds,dx
		movsb
		mov     ds,cx
		add     bx,2
		cmp     bx,2*WINSIZEX
		jb      ZoomLoopX
		pop     bx
		add     di,MAXWIDTH-WINSIZEX
		add     bx,2
		cmp     bx,2*WINSIZEY
		jb      ZoomLoopY
		ret

ZoomBox         endp


;-----------------------------------------------------------------------------
; MandelZoom - Performs the demonstration. Because this routine is called
;   from a High-Level language the allocation and deallocation of memory
;   is done by the caller.
; In:
;   MemSegs - Array of NUMPICS segments of 64K to store the pictures.
;-----------------------------------------------------------------------------

MandelZoom      proc    MemSegs:dword

		mov     ax,13h                  ; set VGA 320x200x256 mode.
		int     10h

		call    SetPalette              ; Sets Color Palette

		les     si,[MemSegs]            ; Creates the Mandelbrot
		mov     cx,NUMPICS              ; piccys into the virtual
		xor     bx,bx                   ; screens.
MakePics:       pusha
		push    ds 
		push    es
		mov     eax,[bx+PicTable+0]     ; get fixedpoint X,Y,DX,DY.
		mov     edx,[bx+PicTable+4]
		mov     esi,[bx+PicTable+8]
		mov     edi,[bx+PicTable+12]    ; Draw Mandelbrot Set.
		call    DrawMandel,eax,edx,esi,edi,0A000h
		pop     es
		pop     ds
		popa

		pusha                           ; Copy Picture:
		push    ds
		push    es
		mov     ax,0A000h               ; get screen segment
		mov     ds,ax
		mov     es,es:[si]              ; get vscreen segment
		xor     di,di
		xor     si,si
		mov     cx,32000                ; copy screen
		cld
		rep     movsw
		call    ClearScreen             ; clears screen
		pop     es
		pop     ds
		popa

		add     si,2                    ; Next Picture Gap.
		add     bx,16
		loop    MakePics

		call    BlackPalette            ; set Black Palette.

DemoLoop:
		mov     cx,NUMFRAMES            ; Zoom-In.
		xor     bx,bx
ZoomIN:         call    WaitVRT
		push    bx
		push    cx
		les     si,[MemSegs]
		mov     ax,[bx+FrameTable+8]    ; PicNo.
		add     si,ax
		add     si,ax
		mov     cx,es:[si]              ; PicSeg.
		mov     ax,[bx+FrameTable+0]    ; XStart.
		mov     dx,[bx+FrameTable+2]    ; YStart.
		mov     si,[bx+FrameTable+4]    ; XStop.
		mov     di,[bx+FrameTable+6]    ; YStop.
		call    ZoomBox,ax,dx,si,di,cx
		pop     cx
		pop     bx
		test    bx,bx
		jne     DontFadeIn
		push    bx
		push    cx
		call    FadeInPalette
		pop     cx
		pop     bx
DontFadeIn:     add     bx,10
		loop    ZoomIN

		mov     cx,NUMFRAMES            ; Zoom-Out.
		mov     bx,10*NUMFRAMES-10
ZoomOUT:        call    WaitVRT
		push    bx
		push    cx
		les     si,[MemSegs]
		mov     ax,[bx+FrameTable+8]    ; PicNo.
		add     si,ax
		add     si,ax
		mov     cx,es:[si]              ; PicSeg.
		mov     ax,[bx+FrameTable+0]    ; XStart.
		mov     dx,[bx+FrameTable+2]    ; YStart.
		mov     si,[bx+FrameTable+4]    ; XStop.
		mov     di,[bx+FrameTable+6]    ; YStop.
		call    ZoomBox,ax,dx,si,di,cx
		pop     cx
		pop     bx
		test    bx,bx
		jne     DontFadeOut
		push    bx
		push    cx
		call    FadeOutPalette
		pop     cx
		pop     bx
DontFadeOut:    sub     bx,10
		loop    ZoomOUT

		mov     ax,03h                  ; set VGA 80x25x16 mode.
		int     10h
		ret

MandelZoom      endp

;-----------------------------------------------------------------------------
; Start - Startup Code called from DOS.
; In:
;   ES - Program Segment Prefix.
;-----------------------------------------------------------------------------

Start           proc
		local   PicSegs:word:NUMPICS

		mov     ax,@Data
		mov     ds,ax
		mov     ax,ss                   ; shrink memory block.
		mov     bx,es
		sub     ax,bx
		mov     bx,sp
		shr     bx,4
		inc     bx
		add     bx,ax
		mov     ah,4Ah
		int     21h

		lea     bx,[PicSegs]
		mov     cx,NUMPICS
AllocLoop:      push    bx
		push    cx
		mov     ah,48h                  ; alloc 64000 bytes per
		mov     bx,4000                 ; picture.
		int     21h
		jc      Exit
		pop     cx
		pop     bx
		mov     ss:[bx],ax
		add     bx,2
		loop    AllocLoop

		lea     bx,[PicSegs]            ; do demostration.
		call    MandelZoom,ss,bx

		lea     bx,[PicSegs]
		mov     cx,NUMPICS              ; Free 64000 bytes
FreeLoop:       push    bx                      ; per picture.
		push    cx
		mov     ah,49h
		mov     es,ss:[bx]
		int     21h
		pop     cx
		pop     bx
		add     bx,2
		loop    FreeLoop

Exit:           mov     ax,4C00h
		int     21h

Start           endp

		end     Start
;=============================================================================
; flame.asm - Plasma-Like Flames Demo.
;                                                    File created: 11/22/93
; Copyright (c) 1993, Carlos Hasan                  Last modified: 11/22/93
;
; Description:
;  Plasma Like Flames effect based on Vangelis Fire Code.
;
; Portability:
;  Requires Turbo Assembler 3.2 or later to be assembled.
;  Dependant on the IBM PC 286 or better processor.
;=============================================================================

	ideal
	model   small
	jumps
	p286

	dosseg
	stack   1024
	ends

	global  FontFAR:byte            ; FLAMES.FNT linked file.

;=========================== VLA Font Header =================================

struc   FontHeader
  Magic   db   "VGACH"                  ; Font Signature
  First   db   ?                        ; First Char
  Width   db   ?                        ; Font Width
  Height  db   ?                        ; Font Height
  Total   db   ?                        ; Number of Chars
ends    FontHeader

;======================== Equates and Data Segment ===========================

TIMEOUT   equ  70*50                    ; At Least 50 secs
MESGSPEED equ  20                       ; Message Speed in VR Ticks
FLSEED    equ  4                        ; Initial Flames Seed
FLBLANK   equ  100                      ; Ending Flames Seed (Blank Screen)
XDOTS     equ  80                       ; VGA Screen Dimensions
YDOTS     equ  80
HIDDEN    equ  8                        ; Number of Hidden Working Lines

	dataseg

label   Palette byte                    ; Flames RGB Palette:
	I=0                             ; black to blue
	rept 8
	db   0,0,2*I
	I=I+1
	endm
	I=0                             ; blue to darkred
	rept 8
	db   2*I,0,16-2*I
	I=I+1
	endm
	I=0                             ; darkred to lightred
	rept 24
	db   16+47*I/24,0,0
	I=I+1
	endm
	I=0                             ; lighred to yellow
	rept 32
	db   63,31*I/16,0
	I=I+1
	endm
	I=0                             ; yellow to white
	rept 24
	db   63,63,21*I/8
	I=I+1
	endm
	rept 160                        ; white
	db   63,63,63
	endm

Frame        dw   XDOTS*(YDOTS+HIDDEN) dup(?)  ; Flames Frame Buffer
Seed         dw   1234h                 ; Random Seed
FontDataOfs  dw   ?                     ; Font Data Address
FontDataSeg  dw   ?
FontWidths   db   256 dup (?)           ; Font Char Widths
FontFirst    db   ?                     ; Font First Char
FontWidth    db   ?                     ; Font Max Width
FontHeight   db   ?                     ; Font Height
FontSize     dw   ?                     ; Font BitMap Size (=Width*Height)

MesgOff      dw   offset TheMessage     ; Message Offset
TheMessage   db   "     FAKE DEMO  CODED BY PELUSA  MUSIC BY NECROS"
	     db   "     GREETS GO TO ALL THE PC DEMO PEOPLE..."
	     db   "     THANKS FOR WATCHING THIS LAME THING..."
	     db   "     SEEING YA........              "
	     db   0


;============================ Code Segment ===================================

	codeseg

;-----------------------------------------------------------------------------
; SetModeX - Sets VGA Tweaked Mode 80x80x256.
;-----------------------------------------------------------------------------

proc    SetModeX
	mov     ax,0013h                ; Set VGA Linear 320x200x256
	int     10h
	mov     dx,3C4h                 ; Disable Chain-Four
	mov     ax,0604h
	out     dx,ax
	mov     dx,3C4h                 ; Enable Write to All Four Planes
	mov     ax,0F02h
	out     dx,ax
	mov     ax,0A000h               ; Clear Display Memory
	mov     es,ax
	xor     di,di
	xor     ax,ax
	mov     cx,8000h
	cld
	rep     stosw
	mov     dx,3D4h                 ; Reprogram CRT Controller:
	mov     ax,00014h               ; turn off dword mode
	out     dx,ax
	mov     ax,0e317h               ; turn on byte mode
	out     dx,ax
	mov     ax,00409h               ; cell height
	out     dx,ax
	ret
endp    SetModeX

;-----------------------------------------------------------------------------
; WaitVR - Waits Vertical Retrace.
;-----------------------------------------------------------------------------

proc    WaitVR
	mov     dx,3DAh
WaitStartVR:
	in      al,dx
	test    al,8
	je      WaitStartVR
WaitEndVR:
	in      al,dx
	test    al,8
	jne     WaitEndVR
	ret
endp    WaitVR

;-----------------------------------------------------------------------------
; LoadFont - Loads the VLA font.
;-----------------------------------------------------------------------------

proc    LoadFont
	mov     ax,SEG FontFAR          ; Load Font File Address
	mov     es,ax
	mov     [FontDataSeg],ax
	mov     [FontDataOfs],Size FontHeader
	mov     al,[es:FontHeader.First] ; Get Font First Char
	mov     [FontFirst],al
	mov     al,[es:FontHeader.Width] ; Get Font Data Size
	mov     ah,[es:FontHeader.Height]
	mov     [FontWidth],al
	mov     [FontHeight],ah
	mul     ah
	mov     [FontSize],ax
	mov     dl,[es:FontHeader.Total]
	xor     dh,dh
	mul     dx
	add     ax,Size FontHeader      ; Copy Font Widths.
	mov     si,ax
	xor     di,di
	mov     cl,[es:FontHeader.Total]
	xor     ch,ch
CopyWidths:
	mov     al,[es:si]
	mov     [FontWidths+di],al
	inc     si
	inc     di
	loop    CopyWidths
	ret
endp    LoadFont

;-----------------------------------------------------------------------------
; DrawChar - Draw a Font Char.
; In:
;  AL = Character Code.
;  ES:DI = Frame Screen Address.
;-----------------------------------------------------------------------------

proc    DrawChar
	sub     al,[FontFirst]          ; Get Char BitMap Offset
	xor     ah,ah
	mov     bx,ax
	mul     [FontSize]
	add     ax,[FontDataOfs]        ; si = char offset
	mov     si,ax
	mov     dl,[FontWidths+bx]      ; dx = char width
	xor     dh,dh
	mov     cl,[FontHeight]         ; cx = char height
	xor     ch,ch
	mov     al,[FontWidth]          ; bp = font max width
	xor     ah,ah
	mov     bp,ax

	mov     ax,XDOTS                ; Draw on Screen Center
	sub     ax,dx
	shr     ax,1
	shl     ax,1
	add     di,XDOTS*(16+YDOTS)
	add     di,ax

	push    ds                      ; ds = font data segment
	mov     ds,[FontDataSeg]
DrawCharLoop:
	push    cx
	push    si
	push    di
	xor     ah,ah
DrawPlane1:
	mov     al,[ds:si]
	test    al,al
	je      SkipColor
	mov     al,0FFh
	mov     [es:di],ax
SkipColor:
	add     si,bp
	add     di,XDOTS*2
	loop    DrawPlane1
	pop     di
	pop     si
	pop     cx
	inc     si
	add     di,2
	dec     dx
	jg      DrawCharLoop
	pop     ds
	ret
endp    DrawChar

;-----------------------------------------------------------------------------
; DrawMesg - Draws the Next Message on the Screen.
;-----------------------------------------------------------------------------

proc    DrawMesg
	pusha
	push    es
	mov     ax,ds                   ; Loads Frame Area Address
	mov     es,ax
	lea     di,[Frame] 
	cld
	mov     si,[MesgOff]
	lodsb
	test    al,al
	stc
	je      DrawMesgExit
	mov     [MesgOff],si
	call    DrawChar
	clc
DrawMesgExit:
	pop     es
	popa
	ret
endp    DrawMesg

;-----------------------------------------------------------------------------
; Random - Returns a random number of 16 bits.
;-----------------------------------------------------------------------------

proc    Random
	mov     ax,[Seed]
	imul    ax,8905h
	inc     ax
	mov     [Seed],ax
	ret
endp    Random

;-----------------------------------------------------------------------------
; Flames - Flames Like Screen Animation.
;-----------------------------------------------------------------------------

proc    Flames
	pusha
	push    ds
	push    es

	call    SetModeX                ; Sets VGA 80x80x256 graphics mode

	call    LoadFont
	mov     [MesgOff],offset TheMessage

	call    WaitVR
	lea     si,[Palette]            ; Sets Color Palette
	mov     cx,768
	mov     dx,3C8h
	xor     al,al
	out     dx,al
	inc     dx
	cld
	rep     outsb
	mov     ax,ds                   ; Clears Frame Buffer
	mov     es,ax
	lea     di,[Frame]
	mov     cx,XDOTS*(YDOTS+HIDDEN)
	xor     ax,ax
	rep     stosw
	mov     ax,0A000h               ; Set Display Memory Segment
	mov     es,ax
	mov     bx,FLSEED               ; Loads Flames Seed Factor
	xor     bp,bp                   ; Start Timer Counter
	 
FlamesLoop:
	inc     bp                      ; Increase Timer
	call    WaitVR                  ; Wait Vertical Retrace
	lea     si,[Frame]              ; Write Frame to the Screen
	xor     di,di
	mov     cx,XDOTS*YDOTS/2
WriteFrameLoop:
	lodsw
	mov     dl,al
	lodsw
	mov     dh,al
	mov     ax,dx
	stosw
	loop    WriteFrameLoop

	cmp     bp,TIMEOUT              ; Don't Draw Message while
	jae     DontDrawMesg            ; Fading out the Flames.
	mov     ax,bp
	xor     dx,dx
	mov     cx,MESGSPEED
	div     cx
	test    dx,dx                   ; Draws Messages...
	jne     DontDrawMesg
	call    DrawMesg
	jnc     DontDrawMesg            ; If no more message text,
	mov     bp,TIMEOUT              ; Start fading out...
DontDrawMesg:

	mov     cx,XDOTS*(YDOTS+HIDDEN-2) ; Transform Upper Frame Lines
	lea     si,[Frame+2*XDOTS]
FlamesTransform:
	mov     ax,[ds:si-2]            ; Sets Pixel at (X,Y) like
	add     ax,[ds:si+0]            ; the average of the near four
	add     ax,[ds:si+2]            ; pixels below it:
	add     ax,[ds:si+2*XDOTS]      ; P(X,Y) = (P(X-1,Y+1)+P(X,Y+1)+
	sub     ax,bx                   ;   P(X+1,Y+1)+P(X,Y+2)-Seed)/4
	sar     ax,2
	jge     FlameNotTooLow
	xor     ax,ax
FlameNotTooLow:
	mov     [ds:si-2*XDOTS],ax
	add     si,2
	loop    FlamesTransform

	; Sets New Random Bottom Flames with Colors from 0 to 127.
	lea     si,[Frame+2*XDOTS*(YDOTS+HIDDEN-2)]
	mov     cx,XDOTS
	xor     dx,dx
RandomFlames:
	call    Random                  ; Use Random to Create a New
	test    ax,ax                   ; Flames Bottom Lines
	js      NotNewColor
	call    Random
	mov     dl,al
	and     dl,7Fh
NotNewColor:
	mov     [ds:si],dx
	mov     [ds:si+2*XDOTS],dx
	add     si,2
	loop    RandomFlames
	mov     ah,1                    ; or Any Key Pressed?
	int     16h                     
	je      CheckTimer
	mov     ah,0
	int     16h
	mov     bp,TIMEOUT
CheckTimer:
	cmp     bp,TIMEOUT              ; Timeout?
	jb      FlamesLoop
DecreaseFlames:
	inc     bx                      ; Increase Flames Seed
	cmp     bx,FLBLANK              ; (makes flames more low)
	jbe     FlamesLoop
FlamesExit:
	mov     ax,0003h                ; Set Text Mode 80x25x16
	int     10h
	pop     es
	pop     ds
	popa
	ret
endp    Flames

;-----------------------------------------------------------------------------
; Start - Startup code called from DOS.
;-----------------------------------------------------------------------------

proc    Start
	mov     ax,@Data                ; Set DS Segment
	mov     ds,ax
	mov     bx,ss                   ; Shrink Program Segment
	mov     ax,es
	sub     bx,ax
	mov     ax,sp
	shr     ax,4
	inc     ax
	add     bx,ax
	mov     ah,4Ah
	call    Flames                  ; Do Flames Demo
	mov     ax,4C00h
	int     21h                     ; Exit to DOS.
endp    Start

	end     Start
;=============================================================================
; scrl.asm - Simple Horizontal Scroller.
;                                                   File created: 11/21/93
; Copyright (c) 1993, Carlos Hasan                 Last modified: 11/21/93
;
; Description:
;  Just a simple scroller in VGA ModeX and an external proportional
; font file in VLA chars format. Mainly based on VLA scrollers.
;
; Dependency:
;  Requires Turbo Assembler 3.2 or later to be assembled.
;  Dependant on the IBM PC 286 or better processor.
;=============================================================================

	ideal
	model   small,pascal
	jumps
	p286

	dosseg
	stack   1024
	ends

IFDEF LinkFont
	global  FontFAR:byte            ; SCRL.FNT linked file.
ENDIF

;=========================== VLA Font Header =================================

struc   FontHeader
  Magic   db   "VGACH"                  ; Font Signature
  First   db   ?                        ; First Char
  Width   db   ?                        ; Font Width
  Height  db   ?                        ; Font Height
  Total   db   ?                        ; Number of Chars
ends    FontHeader

;=========================== Data Segment ====================================

	dataseg

SCREENWIDTH     equ  (2*320+8)          ; Logical Screen Width
					; Enough Space for Double-Window
					; and the working hidden area
SCROLLROW       equ  180                ; Scroller Window Start Row.

WinOffs         dw   ?                  ; Window Offset
CharOffs        dw   ?                  ; Char BitMap Offset
MesgOffs        dw   ?                  ; Ascii-Message Offset
FontHead        FontHeader ?            ; Font Header
CharColumn      db   ?                  ; Cur Char Column
FontFirst       db   ?                  ; Font First Char
FontWidth       db   ?                  ; Font Max Width
FontHeight      db   ?                  ; Font Height
FontDataOfs     dw   ?                  ; Font Data Offset
FontDataSeg     dw   ?                  ; Font Data Segment
FontWidths      db   256 dup(?)         ; Font Width Table
FontSize        dw   ?                  ; Font Char Size (Width*Height)

IFNDEF LinkFont
FontFileName    db   "SCRL.FNT",0       ; Font File Name
ENDIF

TheMessage      db   " ... Hello out there ... "
		db   "                        "
		db   " ... I am PELUSA from Chile ... "
		db   "                        "
		db   " ... Just a simple scroller... "
		db   "                        "
		db   " ... only useful to say that it's the FAKE demo ... "
		db   "                        "
		db   " ... you probably could have guessed that ... "
		db   "                        "
		db   " ... I hate scrollers because i have nothing to say..."
		db   "                        "
		db   " ... now enjoy the rest of this LAME thing ... "
		db   "                                    ",0

	codeseg

;-----------------------------------------------------------------------------
; SetModeX - Sets the VGA in Tweaked ModeX 320x400x256.
;-----------------------------------------------------------------------------

proc    SetModeX
	mov     ax,0013h                ; Sets VGA linear 320x200x256
	int     10h
	mov     dx,3C4h                 ; Disable Chain-Four
	mov     ax,0604h
	out     dx,ax
	mov     dx,3C4h                 ; Enable Write to All Four Planes
	mov     ax,0F02h
	out     dx,ax
	mov     ax,0A000h               ; Clear Display Memory
	mov     es,ax
	xor     di,di
	xor     ax,ax
	mov     cx,8000h
	cld
	rep     stosw
	mov     dx,3D4h                 ; Reprogram CRT Controller:
	mov     ax,00014h               ; turn off dword mode
	out     dx,ax
	mov     ax,0e317h               ; turn on byte mode
	out     dx,ax
	mov     ax,00009h               ; cell height
	out     dx,ax
	mov     dx,3D4h                 ; Sets Logical Screen Width
	mov     al,13h
	mov     ah,SCREENWIDTH/8
	out     dx,ax
	ret
endp    SetModeX

;-----------------------------------------------------------------------------
; WaitVR - Waits the Next VGA Vertical Retrace Ending.
;-----------------------------------------------------------------------------

proc    WaitVR
	mov     dx,3DAh
WaitStartVR:
	in      al,dx
	test    al,8
	je      WaitStartVR
WaitEndVR:
	in      al,dx
	test    al,8
	jne     WaitEndVR
	ret
endp    WaitVR

;-----------------------------------------------------------------------------
; InitScroll - Initializes the Scroller Variables.
; Out:
;  CF=1 if function was not successful.
;  CF=0 if function was successful.
;-----------------------------------------------------------------------------

proc    InitScroll
	mov     [WinOffs],0             ; Start Window Column
	mov     [CharColumn],0          ; Start with a ZeroWidth Char
	mov     [CharOffs],0            ; ZeroWidth Char BitMap Address
	lea     ax,[TheMessage]         ; Sets Message Address
	mov     [MesgOffs],ax
	call    LoadFont                ; Load Font Data
	ret
endp    InitScroll

;-----------------------------------------------------------------------------
; DoneScroll - Done Scroller Variables.
;-----------------------------------------------------------------------------

proc    DoneScroll
IFNDEF LinkFont
	mov     es,[FontDataSeg]        ; Free Font Data Segment
	mov     ah,49h
	int     21h
ENDIF
	ret
endp    DoneScroll

;-----------------------------------------------------------------------------
; LoadFont - Loads a New VGA Font.
; Out:
;  CF=1 if function was not successful.
;  CF=0 if function was successful.
;-----------------------------------------------------------------------------

proc    LoadFont

IFDEF LinkFont
	mov     ax,SEG FontFAR          ; Load Font File Address
	mov     es,ax
	mov     [FontDataSeg],ax
	mov     [FontDataOfs],Size FontHeader
	mov     al,[es:FontHeader.First] ; Get Font First Char
	mov     [FontFirst],al
	mov     al,[es:FontHeader.Width] ; Get Font Data Size
	mov     ah,[es:FontHeader.Height]
	mov     [FontWidth],al
	mov     [FontHeight],ah
	mul     ah
	mov     [FontSize],ax
	mov     dl,[es:FontHeader.Total]
	xor     dh,dh
	mul     dx
	add     ax,Size FontHeader      ; Copy Font Widths.
	mov     si,ax
	xor     di,di
	mov     cl,[es:FontHeader.Total]
	xor     ch,ch
CopyWidths:
	mov     al,[es:si]
	mov     [FontWidths+di],al
	inc     si
	inc     di
	loop    CopyWidths
ELSE
	mov     [FontDataSeg],0
	mov     ax,3D00h                ; Open Font File
	lea     dx,[FontFileName]
	int     21h
	jc      LoadFontExit
	mov     bx,ax
	mov     ah,3Fh                  ; Read Font Header
	lea     dx,[FontHead]
	mov     cx,Size FontHeader
	int     21h
	jc      LoadFontExit
	mov     al,[FontHead.First]     ; Get Font First Char
	mov     [FontFirst],al
	mov     al,[FontHead.Width]     ; Get Font Data Size
	mov     ah,[FontHead.Height]
	mov     [FontWidth],al
	mov     [FontHeight],ah
	mul     ah
	mov     [FontSize],ax
	mov     dl,[FontHead.Total]
	xor     dh,dh
	mul     dx
	push    ax
	push    bx                      ; Alloc Space for Font Data
	mov     bx,ax
	shr     bx,4
	inc     bx
	mov     ah,48h
	int     21h
	pop     bx
	pop     cx
	jc      LoadFontExit
	push    ds                      ; Read Font Data
	mov     [FontDataSeg],ax
	mov     [FontDataOfs],0
	mov     ds,ax
	xor     dx,dx
	mov     ah,3Fh
	int     21h
	pop     ds
	jc      LoadFontExit
	lea     dx,[FontWidths]         ; Read Font Widths
	mov     cl,[FontHead.Total]
	xor     ch,ch
	mov     ah,3Fh
	int     21h
	jc      LoadFontExit
	mov     ah,3Eh                  ; Close Font File
	int     21h
ENDIF
LoadFontExit:
	ret
endp    LoadFont

;-----------------------------------------------------------------------------
; DrawScroll - Polls the Horizontal Scroller.
; Out:
;  CF=1 If no more scroll message.
;  CF=0 If more scroll message.
;-----------------------------------------------------------------------------

proc    DrawScroll
	mov     bx,[WinOffs]            ; Loads Window Offset
	add     bx,2
	mov     dx,3D4h                 ; Sets VGA Start Address
	mov     al,0Dh
	mov     ah,bl
	out     dx,ax
	dec     al
	mov     ah,bh
	out     dx,ax
	sub     [CharColumn],4          ; Advance 4 pixels
	jg      NoNewChar               ; Need a New Char?
	call    GetsNewChar             ; Yes, Draw a New Char
	jc      DrawScrollExit
NoNewChar:
	mov     ax,0A000h               ; Loads Display Memory Segment
	mov     es,ax
	mov     bl,[FontWidth]          ; Loads Font Width and Height
	mov     cl,[FontHeight]
	xor     bh,bh
	xor     ch,ch
	mov     bp,SCREENWIDTH/4        ; Loads Logical Screen Width

	mov     dx,3C4h                 ; Enable Write to Plane 1
	mov     ax,0102h
	out     dx,ax
	mov     si,[CharOffs]           ; Loads Char BitMap Address
	mov     di,[WinOffs]            ; Loads VGA Window Dest Address
	add     di,SCROLLROW*SCREENWIDTH/4
	push    cx
	push    ds
	mov     ds,[FontDataSeg]
DrawCharColumn1:
	mov     al,[ds:si]
	mov     [es:di],al
	mov     [es:di+SCREENWIDTH/8],al
	add     si,bx
	add     di,bp
	loop    DrawCharColumn1
	pop     ds
	pop     cx

	mov     dx,3C4h                 ; Enable Write to Plane 2
	mov     ax,0202h
	out     dx,ax
	mov     si,[CharOffs]           ; Loads Char BitMap Address
	mov     di,[WinOffs]            ; Loads VGA Window Dest Address
	inc     si
	add     di,SCROLLROW*SCREENWIDTH/4
	push    cx
	push    ds
	mov     ds,[FontDataSeg]
DrawCharColumn2:
	mov     al,[ds:si]
	mov     [es:di],al
	mov     [es:di+SCREENWIDTH/8],al
	add     si,bx
	add     di,bp
	loop    DrawCharColumn2
	pop     ds
	pop     cx

	mov     dx,3C4h                 ; Enable Write to Plane 3
	mov     ax,0402h
	out     dx,ax
	mov     si,[CharOffs]           ; Loads Char BitMap Address
	mov     di,[WinOffs]            ; Loads VGA Window Dest Address
	add     si,2
	add     di,SCROLLROW*SCREENWIDTH/4
	push    cx
	push    ds
	mov     ds,[FontDataSeg]
DrawCharColumn3:
	mov     al,[ds:si]
	mov     [es:di],al
	mov     [es:di+SCREENWIDTH/8],al
	add     si,bx
	add     di,bp
	loop    DrawCharColumn3
	pop     ds
	pop     cx

	mov     dx,3C4h                 ; Enable Write to Plane 4
	mov     ax,0802h
	out     dx,ax
	mov     si,[CharOffs]           ; Loads Char BitMap Address
	mov     di,[WinOffs]            ; Loads VGA Window Dest Address
	add     si,3
	add     di,SCROLLROW*SCREENWIDTH/4
	push    cx
	push    ds
	mov     ds,[FontDataSeg]
DrawCharColumn4:
	mov     al,[ds:si]
	mov     [es:di],al
	mov     [es:di+SCREENWIDTH/8],al
	add     si,bx
	add     di,bp
	loop    DrawCharColumn4
	pop     ds
	pop     cx

	inc     [WinOffs]               ; Advance Window by 4 pixels
	cmp     [WinOffs],SCREENWIDTH/8
	jb      DontWrapWindow
	mov     [WinOffs],0
DontWrapWindow:
	add     [CharOffs],4            ; Advance Char Column by 4
	clc
DrawScrollExit:
	ret
endp    DrawScroll

;-----------------------------------------------------------------------------
; GetsNewChar - Gets the next message Character.
; Out:
;  CF=1 If no more characters
;  CF=0 If more characters
;-----------------------------------------------------------------------------

proc    GetsNewChar
	mov     si,[MesgOffs]           ; Loads the Message Offset
GetCharLoop:
	lodsb                           ; Gets the Character
	test    al,al                   ; if End of Message ReStart
	jne     DrawCharNow
	stc
	jmp     GetsNewCharExit
DrawCharNow:
	mov     [MesgOffs],si           ; Save Message Offset
	sub     al,[FontFirst]          ; Compute the Char BitMap Address
	xor     ah,ah
	mov     bx,ax
	mov     dx,[FontSize]
	mul     dx
	add     ax,[FontDataOfs]
	mov     [CharOffs],ax
	mov     al,[FontWidths+bx]      ; Set the Char Width
	mov     [CharColumn],al
	clc
GetsNewCharExit:
	ret
endp    GetsNewChar


;-----------------------------------------------------------------------------
; Start - Start the Demostration. Called from DOS.
;-----------------------------------------------------------------------------

proc    Start
	mov     ax,@Data                ; Sets Data Segment.
	mov     ds,ax
	mov     bx,sp                   ; Shrink Program Memory Block.
	shr     bx,4
	inc     bx
	mov     ax,ss
	mov     dx,es
	sub     ax,dx
	add     bx,ax
	mov     ah,4Ah
	int     21h
	call    SetModeX                ; Sets VGA ModeX.
	call    InitScroll              ; Init Scroller.
	jc      DemoExit
	cld
DemoLoop:
	call    WaitVR                  ; Waits Vertical Retrace.
	call    DrawScroll              ; Draw the Scroller.
	jc      DemoBreak
	mov     ah,1                    ; Any Key Pressed?
	int     16h                     ; No, Loop.
	je      DemoLoop
DemoBreak:
	call    DoneScroll              ; Done Scroller.
DemoExit:
	mov     ax,0003h                ; Set Text Mode.
	int     10h
	mov     ax,4C00h                ; Exit to DOS.
	int     21h
endp    Start

	end     Start
;=============================================================================
; cplasma - Real Color plasma clouds demo.
;                                                     File created: 9-28-93
;                                                    Last modified: 9-28-93
; Description:
;   This file implements the real color plasma demostration using the
;   plasma routines and palette rotation using the VGA 320x200x256 mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;=============================================================================

		.model  small,pascal
		 jumps
		.286

		global  DrawPlasma:proc         ; in PLASMA.ASM file.
		global  ColorPlasma:proc

;===================== Demo equates and data =================================

TIMEOUT         equ     70 * 6                  ; 6 seconds timeout.

		.data

Palette         db      768 dup (?)             ; hold the palette.
FadePalette     db      768 dup (?)             ; hold the faded palette.
Fade            db      ?                       ; fade level.
EscKey          db      ?                       ; true if ESC pressed.
Timer           dw      ?                       ; timer counter.

;========================== Demo routines ====================================

		.code

;-----------------------------------------------------------------------------
; WaitVRT - Waits the Vertical Retrace Period.
;-----------------------------------------------------------------------------

WaitVRT         proc near

		push    ax
		push    dx
		mov     dx,3DAh
WaitVRT1:       in      al,dx
		test    al,8
		jz      WaitVRT1
WaitVRT2:       in      al,dx
		test    al,8
		jnz     WaitVRT2
		pop     dx
		pop     ax
		ret

WaitVRT         endp

;-----------------------------------------------------------------------------
; SetPalette - set the 256 entries of the VGA color palette.
; In:
;   DS:SI - Palette structure address.
;-----------------------------------------------------------------------------

SetPalette      proc near

		mov     cx,768
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		mov     dx,3DAh
WaitVR1:        in      al,dx
		test    al,8
		jz      WaitVR1
		mov     dx,3C9h
		rep     outsb
WaitVR2:        in      al,dx
		test    al,8
		jnz     WaitVR2
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; ColorPlasma - Performs the demonstration.
; In:
;   DS - Data segment.
;-----------------------------------------------------------------------------

ColorPlasma      proc

		mov     ax,0013h                ; set 320x200x256 mode.
		int     10h

		mov     [Fade],0                ; setup variables.
		mov     [EscKey],0
		mov     [Timer],0

		lea     di,[FadePalette]        ; clear fade palette.
		mov     ax,ds
		mov     es,ax
		mov     cx,768
		xor     ax,ax
		cld
		rep     stosb
		lea     si,[FadePalette]
		call    SetPalette              ; set black palette.

GenPalette:     lea     di,[Palette]            ; generation of the
		xor     cx,cx                   ; plasma palette.
GP0:            mov     al,63
		mov     ah,cl
		mov     bl,al
		sub     bl,cl
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp0

		xor     cx,cx
Gp1:            mov     al,63
		sub     al,cl
		mov     ah,63
		mov     bl,cl
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp1

		xor     cx,cx
Gp2:            mov     al,0
		mov     ah,63
		sub     ah,cl
		mov     bl,63
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp2

		xor     cx,cx
Gp3:            mov     al,cl
		mov     ah,0
		mov     bl,63
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp3

		; draw plasma onto VGA screen.

		call    DrawPlasma,30,36,290,164,01234h,0A000h

		mov     ax,ds
		mov     es,ax
		cld

PlasmaLoop:     test    [Timer],1               ; decreases the rot speed.
		jne     DontRotate
		lea     bx,[Palette]            ; rotate the palette.
		mov     si,bx
		mov     di,bx
		add     si,9
		mov     cx,768-9
		rep     movsb
		mov     si,bx
		mov     cx,9
		rep     movsb
		mov     di,bx
		xor     al,al
		mov     cx,9
		rep     stosb
DontRotate:

		cmp     [EscKey],0              ; change the fade level.
		jne     FadeOut
FadeIn:         mov     bl,[Fade]
		cmp     bl,128
		jae     FadeInOut
		inc     [Fade]
		jmp     FadeInOut

FadeOut:        mov     bl,[Fade]
		cmp     bl,0
		jbe     FadeInOut
		dec     [Fade]

FadeInOut:      lea     si,[Palette]            ; set fade palette using
		lea     di,[FadePalette]        ; the current fade level
		mov     cx,768                  ; and plasma palette.
FadeLoop:       lodsb
		mul     bl
		shr     ax,7
		stosb
		loop    FadeLoop

		lea     si,[FadePalette]        ; set VGA fade-palette.
		call    SetPalette

		mov     ah,1                    ; if any key pressed,
		int     16h
		jz      CheckTimer
		mov     ah,0
		int     16h
		jmp     BeginFadeOut

CheckTimer:     inc     [Timer]                 ; or timeout...
		cmp     [Timer],TIMEOUT
		jb      CheckExit

BeginFadeOut:   inc     [EscKey]                ; start fade-out and exit.

CheckExit:      cmp     [Fade],0                ; if fade-out is done
		jne     PlasmaLoop              ; then quit.

		mov     ax,0003h                ; restore 80x25x16 text mode.
		int     10h

		ret

ColorPlasma      endp


		end
;=============================================================================
; plasma.asm - Plasma Clouds fractal calculation routine.
;                                                     File created: 9-26-93
; Copyright (c) 1993, Carlos Hasan                   Last modified: 9-26-93
;
; Description:
;  This file implements the plasma clouds routine using a recursive algorithm
;  optimized for use with VGA 320x200x256 graphics mode. There must be enough
;  stack space for this routine.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 286 or later microprocessor.
;=============================================================================

		.model  small,pascal
		.286

		global  DrawPlasma:proc

;===================== Plasma equates ========================================

MAXWIDTH        equ     320                     ; virtual screen dimensions.
MAXHEIGHT       equ     200
MAXCOLOR        equ     255                     ; max colors for plasma.
SHIFTVALUE      equ     2                       ; granularity shift.

;====================== Plasma data ==========================================

		.data

RandSeed        dw      ?                       ; random generator seed.

;====================== Plasma routines ======================================

		.code

;-----------------------------------------------------------------------------
; Random - Returns a random number of 16 bits, modified version of the
;  ripped System unit random routine of the Borland Pascal 7.0.
; Out:
;  AX - random value.
; Modified:
;  AX, DX, Flags.
;-----------------------------------------------------------------------------

Random          proc near

		mov     ax,[RandSeed]
		mov     dx,8405h
		mul     dx
		inc     ax
		mov     [RandSeed],ax
		ret

Random          endp


;-----------------------------------------------------------------------------
; GetPixel - get the pixel color at specified location.
; In:
;   ES    - virtual screen segment.
;   (X,Y) - pixel location.
; Out:
;   AL    - pixel color value.
; Modified:
;   BX, Flags.
;-----------------------------------------------------------------------------

GetPixel        macro   X,Y

		mov     bx,Y
		imul    bx,MAXWIDTH
		add     bx,X
		mov     al,es:[bx]

		endm

;-----------------------------------------------------------------------------
; PutPixel - put the pixel color at specified location.
; In:
;   ES    - virtual screen segment.
;   (X,Y) - pixel location.
;   AL    - pixel value.
; Modified:
;   BX, Flags.
;-----------------------------------------------------------------------------

PutPixel        macro   X,Y

		mov     bx,Y
		imul    bx,MAXWIDTH
		add     bx,X
		mov     es:[bx],al

		endm


;----------------------------------------------------------------------------
; Adjust - adjust a new pixel value using two neighboring pixels.
; In:
;  (XA,YA) - first near pixel.
;  (XB,YB) - second near pixel.
;  (X,Y)   - new pixel.
; Out:
;  AX      - new pixel color value.
; Modified:
;  AX, BX, DX, SI, DI, Flags.
;----------------------------------------------------------------------------

Adjust          proc near XA:word,YA:word,X:word,Y:word,XB:word,YB:word

		mov     si,[X]                  ; if already painted
		mov     di,[Y]                  ; the pixel, use this
		xor     ax,ax                   ; one instead of new
		GetPixel si,di                  ; calculation.
		test    ax,ax
		jne     AdjExit

		call    Random                  ; get a random variation
		mov     bx,[XB]                 ; dependent of the pixels
		sub     bx,[XA]                 ; distance and granularity
		add     bx,[YB]                 ; shift factor.
		sub     bx,[YA]
		shl     bx,SHIFTVALUE
		imul    bx
		xor     ax,ax                   ; adds the average of the
		GetPixel [XA],[YA]              ; near pixels colors.
		add     dx,ax
		GetPixel [XB],[YB]
		add     ax,dx
		shr     ax,1
		cmp     ax,1                    ; check if new color is
		jge     ColorUp                 ; in the right range.
		mov     ax,1
ColorUp:        cmp     ax,MAXCOLOR
		jle     ColorDn
		mov     ax,MAXCOLOR
ColorDn:        PutPixel si,di                  ; paint pixel color.
AdjExit:        ret

Adjust          endp


;-----------------------------------------------------------------------------
; SubDivide - main plasma routine that divides a region recursively.
; In:
;   (X1,Y1,X2,Y2) - screen plasma region.
; Modified:
;   AX, BX, CX, DX, Flags.
;-----------------------------------------------------------------------------

SubDivide       proc near X1:word,Y1:word,X2:word,Y2:word
		local   X:word,Y:word

		mov     ax,[X2]                 ; test if this region
		sub     ax,[X1]                 ; needs a sub-division.
		cmp     ax,2
		jge     SubDivCont
		mov     ax,[Y2]
		sub     ax,[Y1]
		cmp     ax,2
		jge     SubDivCont
		jmp     SubDivExit

SubDivCont:     mov     ax,[X1]                 ; get the center position
		add     ax,[X2]                 ; of the region.
		rcr     ax,1
		mov     [X],ax
		mov     ax,[Y1]
		add     ax,[Y2]
		rcr     ax,1
		mov     [Y],ax

		; get the sum of the neighboring four pixel colors.
		xor     cx,cx
		call    Adjust, [X1],[Y1], [X],[Y1], [X2],[Y1]
		add     cx,ax
		call    Adjust, [X2],[Y1], [X2],[Y], [X2],[Y2]
		add     cx,ax
		call    Adjust, [X1],[Y2], [X],[Y2], [X2],[Y2]
		add     cx,ax
		call    Adjust, [X1],[Y1], [X1],[Y], [X1],[Y2]
		add     cx,ax

		mov     si,[X]                  ; test if the center pixel
		mov     di,[Y]                  ; need to be calculated.
		GetPixel si,di
		test    al,al
		jne     SubDivNow
		mov     ax,cx                   ; yes, use the average of
		add     ax,2                    ; the neighboring pixels.
		shr     ax,2                    ; (don't allow color 0)
		PutPixel si,di

		; sub-divides the new four regions.
SubDivNow:      call    SubDivide, [X1],[Y1], [X],[Y]
		call    SubDivide, [X],[Y1], [X2],[Y]
		call    SubDivide, [X],[Y], [X2],[Y2]
		call    SubDivide, [X1],[Y], [X],[Y2]

SubDivExit:     ret

SubDivide       endp

;-----------------------------------------------------------------------------
; DrawPlasma - Main routine to draw plasma into a virtual screen.
; In:
;   (X1,Y1,X2,Y2) - Virtual screen Window location.
;   Seed          - Initial random seed for the plasma generator.
;   ScreenSeg     - Virtual screen segment.
;-----------------------------------------------------------------------------

DrawPlasma      proc    XStart:word,YStart:word,XStop:word,YStop:word, \
		  Seed:word,ScreenSeg:word

		mov     ax,[ScreenSeg]          ; setup virtual screen
		mov     es,ax                   ; segment,

		mov     ax,[Seed]               ; and random calculation
		mov     [RandSeed],ax           ; seed.

		call    Random                  ; set window corner pixels.
		or      al,1
		PutPixel [XStart],[YStart]

		call    Random
		or      al,1
		PutPixel [XStop],[YStart]

		call    Random
		or      al,1
		PutPixel [XStart],[YStop]

		call    Random
		or      al,1
		PutPixel [XStop],[YStop]

		call    SubDivide, [XStart],[YStart], [XStop],[YStop]
		ret

DrawPlasma      endp

		end;=============================================================================
; rplasma - Runtime real plasma clouds demo.
;                                                   File created: 9-28-93
; Copyright (C) 1993, Carlos Hasan                 Last modified: 9-28-93
;
; Description:
;   This file implements a runtime real plasma using sinus overlapping
;   waves at random speeds using the VGA 320x400x256 mode. Based on the
;   Vangelis Plasma demo code.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;=============================================================================

		.model  small,pascal
		.286

		global  SinusPlasma:proc

;======================= Demo equates and data ===============================

TIMEOUT         equ     70 * 6                  ; 6 secs for timeout.

		.data

		include sintable.inc            ; sinus table.

Palette         db      768 dup (?)             ; plasma palette.
FadePalette     db      768 dup (?)             ; faded palette.
WavHPos1        db      ?                       ; wave horizontal and
WavHPos2        db      ?                       ; vertical positions
WavVPos1        db      ?                       ; and increments.
WavVPos2        db      ?
WavHAdd1        db      ?                       ; WARNING: the four waves
WavHAdd2        db      ?                       ;  positions must be at
WavVAdd1        db      ?                       ;  consecutive addresses.
WavVAdd2        db      ?
Fade            db      ?                       ; fade level.
Esckey          db      ?                       ; true if key pressed.
Timer           dw      ?                       ; timer counter.

;======================= Demo routines =======================================

		.code

;-----------------------------------------------------------------------------
; SetPalette - set the 256 entries of the VGA color palette.
; In:
;   DS:SI - Palette structure address.
;-----------------------------------------------------------------------------

SetPalette      proc near

		mov     cx,768
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		mov     dx,3DAh
WaitVRT:        in      al,dx
		test    al,8
		jz      WaitVRT
		mov     dx,3C9h
		rep     outsb
WaitVRTE:       in      al,dx
		test    al,8
		jnz     WaitVRTE
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; SinusPlasma - Performs the demonstration.
; In:
;   DS - Data segment.
;-----------------------------------------------------------------------------

SinusPlasma     proc

		pusha
		push    ds
		push    es

		mov     ax,0013h                ; set 320x200x256 mode.
		int     10h

		mov     ax,ds                   ; set black palette.
		mov     es,ax
		lea     di,[FadePalette]
		mov     cx,768
		xor     ax,ax
		cld
		rep     stosb
		lea     si,[FadePalette]
		call    SetPalette

		mov     dx,3C4h                 ; setup VGA tricky
		mov     ax,0604h                ; 320x400x256 mode.
		out     dx,ax
		mov     ax,0F02h                ; enable 4-planes.
		out     dx,ax
		mov     dx,3D4h                 ; disable dword mode
		mov     ax,0014h
		out     dx,ax
		mov     ax,0E317h               ; enable byte mode
		out     dx,ax
		mov     ax,0009h                ; dup each scan 1 times
		out     dx,ax

		mov     ax,0A000h
		mov     es,ax
		xor     di,di
		mov     cx,8000h                ; clear video memory.
		xor     ax,ax
		cld
		rep     stosw

		mov     [Fade],0                ; setup variables.
		mov     [EscKey],0
		mov     [Timer],0

		mov     [WavHPos1],0            ; setup wave parameters.
		mov     [WavHPos2],0
		mov     [WavVPos1],0
		mov     [WavVPos2],0
		mov     [WavHAdd1],2
		mov     [WavHAdd2],1
		mov     [WavVAdd1],3
		mov     [WavVAdd2],4

GenPalette:     lea     di,[Palette]            ; generation of the
		xor     al,al                   ; plasma palette.
		mov     [di+0],al
		mov     [di+1],al
		mov     [di+2],al
		add     di,3
		mov     cx,1
GP0:            mov     al,63
		mov     ah,cl
		mov     bl,al
		sub     bl,cl
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp0

		xor     cx,cx
Gp1:            mov     al,63
		sub     al,cl
		mov     ah,63
		mov     bl,cl
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp1

		xor     cx,cx
Gp2:            mov     al,0
		mov     ah,63
		sub     ah,cl
		mov     bl,63
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp2

		xor     cx,cx
Gp3:            mov     al,cl
		mov     ah,0
		mov     bl,63
		mov     [di+0],al
		mov     [di+1],ah
		mov     [di+2],bl
		add     di,3
		inc     cx
		cmp     cx,64
		jb      Gp3

PlasmaLoop:     cmp     [EscKey],0              ; change fade level.
		jne     FadeOut
FadeIn:         mov     bl,[Fade]
		cmp     bl,64
		jae     SkipFade
		inc     [Fade]
		jmp     FadeInOut
FadeOut:        mov     bl,[Fade]
		cmp     bl,0
		jbe     FadeInOut
		dec     [Fade]

FadeInOut:      lea     si,[Palette]            ; set faded palette.
		lea     di,[FadePalette]
		mov     cx,768
		mov     ax,ds
		mov     es,ax
		cld
FadeLoop:       lodsb
		mul     bl
		shr     ax,6
		stosb
		loop    FadeLoop

SkipFade:       lea     si,[FadePalette]
		call    SetPalette

		mov     ax,0A000h
		mov     es,ax

		lea     si,[SinusTable]

		mov     di,80*100+10            ; top left corner.

		mov     ah,100                  ; 100 lines.
		mov     cl,[WavVPos1]
		mov     ch,[WavVPos2]
VertLoop:       push    ax
		mov     ah,60                   ; 60 columns.
		mov     dl,[WavHPos1]
		mov     dh,[WavHPos2]
HorizLoop:      mov     bx,bp                   ; get random value.
		mov     al,bl
		xor     bh,bh
		mov     bl,dl
		add     al,[bx+si]
		mov     bl,dh
		add     al,[bx+si]
		mov     bl,cl
		add     al,[bx+si]
		mov     bl,ch
		add     al,[bx+si]
		or      al,1
		stosb
		add     dl,1
		add     dh,3
		dec     ah
		jne     HorizLoop
		add     di,80+20                ; skip scan line.
		add     cl,7
		add     ch,3
		pop     ax
		dec     ah
		jne     VertLoop                ; next plasma line.

		inc     bp                      ; get random value.
		mov     bx,bp
		xor     bl,bh
		xor     bl,[di-1]
		xor     bl,cl
		xor     bl,dl
		add     bl,ch
		add     bl,dh

		test    bl,8                    ; change waves speed.
		jne     SpeedDown
SpeedUp:        and     bx,3
		cmp     [WavHAdd1+bx],+7
		jg      ChangePos
		inc     [WavHAdd1+bx]
		jmp     ChangePos
SpeedDown:      and     bx,3
		cmp     [WavHAdd1+bx],-7
		jl      ChangePos
		dec     [WavHAdd1+bx]

ChangePos:      mov     al,[WavHAdd1]           ; change waves positions.
		add     [WavHPos1],al
		mov     al,[WavHAdd2]
		add     [WavHPos2],al
		mov     al,[WavVAdd1]
		add     [WavVPos1],al
		mov     al,[WavVAdd2]
		add     [WavVPos2],al

		mov     ah,1                    ; if any key pressed,
		int     16h
		jz      CheckTimer
		mov     ah,0
		int     16h
		jmp     BeginFadeOut

CheckTimer:     inc     [Timer]                 ; or timeout,
		cmp     [Timer],TIMEOUT
		jb      CheckExit

BeginFadeOut:   inc     [EscKey]                ; then fade-out and exit.

CheckExit:      cmp     [Fade],0
		je      PlasmaExit
		jmp     PlasmaLoop

PlasmaExit:     mov     ax,0003h
		int     10h

		pop     es
		pop     ds
		popa
		ret

SinusPlasma     endp

		end
;=============================================================================
; wplasma - Runtime Sinus Wave Plasma Demostration.
;                                                   File created: 10-21-93
; Copyright (C) 1993, Carlos Hasan                 Last modified: 10-21-93
;
; Description:
;   This file implements a runtime real plasma using sinus overlapping
;   waves at random speeds using the VGA 320x80x256 mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembler.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;=============================================================================

		jumps
		.model  small,pascal
		.286

		global  WavePlasma:proc

;======================= Demo equates and data ===============================

TIMEOUT         equ     70 * 10                 ; at least 10 secs.
MAXHW           equ     32                      ; max horiz wave amount.
MAXVW           equ     64                      ; max vert wave amount.
MAXH            equ     60                      ; horiz wave length.
MAXV            equ     80+MAXHW                ; vert wave length.
SEED            equ     57FEh                   ; randomize.

		.data

		include sintab2.inc             ; sinus table.

HWave1          db      MAXH dup (?)            ; horiz waves.
HWave2          db      MAXH dup (?)
VWave1          db      MAXV dup (?)            ; vert waves.
VWave2          db      MAXV dup (?)
HWavPos1        dw      ?                       ; horiz waves pos.
HWavPos2        dw      ?
VWavPos1        dw      ?                       ; vert waves pos.
VWavPos2        dw      ?
HWavInc1        dw      ?                       ; horiz wave speed.
VWavInc1        dw      ?                       ; vert wave speed.
Bitmap          db      256*MAXH+MAXV dup (?)   ; aux plasma buffer.

Palette         db      768 dup (?)             ; plasma palette.
FadePalette     db      768 dup (?)             ; faded palette.
Fade            db      ?                       ; fade level.
Esckey          db      ?                       ; true if key pressed.
Timer           dw      ?                       ; timer counter.
RandSeed        dw      ?                       ; Random seed.

;======================= Demo routines =======================================

		.code

;-----------------------------------------------------------------------------
; Random - Returns a 16-bit random number.
; Out:
;  AX - Random number.
;-----------------------------------------------------------------------------

Random          proc near

		mov     ax,[RandSeed]
		imul    ax,13A7h
		inc     ax
		mov     [RandSeed],ax
		ret

Random          endp

;-----------------------------------------------------------------------------
; WaitVRT - Waits the Vertical Retrace.
;-----------------------------------------------------------------------------

WaitVRT         proc near

		mov     dx,3DAh
WaitVR1:        in      al,dx
		test    al,8
		jne     WaitVR1
WaitVR2:        in      al,dx
		test    al,8
		je      WaitVR2
		ret

WaitVRT         endp

;-----------------------------------------------------------------------------
; SetPalette - set the CX entries of the VGA color palette.
; In:
;   DS:SI - Palette structure address.
;   CX    - Number of colors components.
;-----------------------------------------------------------------------------

SetPalette      proc near

		call    WaitVRT
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		inc     dx
		rep     outsb
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; UpdHWaves - Updates the Horiz Waves.
;-----------------------------------------------------------------------------

UpdHWaves       proc near

		mov     ax,ds
		mov     es,ax
		cld
		lea     si,[HWave1+1]
		lea     di,[HWave1]
		mov     cx,MAXH-1
		rep     movsb
		mov     si,[HWavPos1]
		mov     al,[SinusTable+si]
		sar     al,1
		stosb
		add     si,[HWavInc1]
		cmp     si,360
		jb      SetHInc
		sub     si,360
SetHInc:        mov     [HWavPos1],si
		lea     si,[SinusTable]
		add     si,[HWavPos2]
		lea     bx,[HWave1]
		lea     di,[HWave2]
		mov     cx,MAXH
UpdHLoop:       lodsb
		sar     al,1
		add     al,[bx]
		sar     al,3
		add     al,16
		stosb
		add     si,3
		inc     bx
		loop    UpdHLoop
		add     [HWavPos2],4
		cmp     [HWavPos2],360
		jb      UpdHExit
		sub     [HWavPos2],360
UpdHExit:       ret

UpdHWaves       endp

;-----------------------------------------------------------------------------
; UpdVWaves - Updates the Vert Waves.
;-----------------------------------------------------------------------------

UpdVWaves       proc near

		mov     ax,ds
		mov     es,ax
		cld
		lea     si,[VWave1+1]
		lea     di,[VWave1]
		mov     cx,MAXV-1
		rep     movsb
		mov     si,[VWavPos1]
		mov     al,[SinusTable+si]
		sar     al,1
		stosb
		add     si,[VWavInc1]
		cmp     si,360
		jb      SetVInc
		sub     si,360
SetVInc:        mov     [VWavPos1],si
		lea     si,[SinusTable]
		add     si,[VWavPos2]
		lea     bx,[VWave1]
		lea     di,[VWave2]
		mov     cx,MAXV
UpdVLoop:       lodsb
		sar     al,1
		add     al,[bx]
		sar     al,2
		add     al,32
		stosb
		add     si,2
		inc     bx
		loop    UpdVLoop
		inc     [VWavPos2]
		cmp     [VWavPos2],360
		jb      UpdVExit
		sub     [VWavPos2],360
UpdVExit:       ret

UpdVWaves       endp

;-----------------------------------------------------------------------------
; UpdBmp - Updates the Plasma bitmap.
;-----------------------------------------------------------------------------

UpdBmp          proc near

		cld
		mov     cx,MAXV
		lea     si,[VWave2]
		lea     di,[BitMap]
UpBmLoop:       lodsb
		i=0
		REPT MAXH
		  inc   al
		  mov   [di+i],al
		  i=i+256
		ENDM
		inc     di
		loop    UpBmLoop
		ret

UpdBmp          endp

;-----------------------------------------------------------------------------
; PutBmp - Puts into the screen the Plasma bitmap.
;-----------------------------------------------------------------------------

PutBmp          proc near

		cld
		mov     ax,0A000h
		mov     es,ax
		mov     di,80*10
		lea     dx,[BitMap]
		lea     si,[HWave2]
		mov     bl,MAXH
		xor     ah,ah
PutLoop:        lodsb
		push    si
		mov     si,ax
		add     si,dx
		mov     cx,40
		rep     movsw
		pop     si
		inc     dh
		dec     bl
		jne     PutLoop
		ret

PutBmp          endp

;-----------------------------------------------------------------------------
; WavePlasma - Performs the demonstration.
; In:
;   DS - Data segment.
;-----------------------------------------------------------------------------

WavePlasma      proc

		pusha
		push    ds
		push    es

		mov     ax,0013h                ; set 320x200x256 mode.
		int     10h

		mov     dx,3C4h                 ; disable chain-four
		mov     al,04h
		out     dx,al
		inc     dx
		in      al,dx
		and     al,0F7h
		out     dx,al
		mov     dx,3C4h                 ; enable all planes
		mov     ax,0F02h
		out     dx,ax
		mov     ax,0A000h               ; clear video memory
		mov     es,ax
		xor     di,di
		xor     ax,ax
		mov     cx,8000h
		cld
		rep     stosw
		mov     dx,3D4h                 ; normal word addressing
		mov     al,14h
		out     dx,al
		inc     dx
		in      al,dx
		and     al,0BFh
		out     dx,al
		dec     dx                      ; address output byte mode
		mov     al,17h
		out     dx,al
		inc     dx
		in      al,dx
		or      al,40h
		out     dx,al
		mov     dx,3D4h                 ; set max scanline.
		mov     ax,0409h
		out     dx,ax

GenPalette:     lea     di,[Palette]            ; generation of the
		xor     al,al                   ; plasma palette.
		mov     [di+0],al
		mov     [di+1],al
		mov     [di+2],al
		add     di,3
		mov     cx,MAXH+MAXVW
		xor     ah,ah
		mov     bl,2
GPLoop:         mov     dl,32
		mov     al,ah
		shr     al,1
		sub     dl,al
		mov     [di+0],dl
		mov     dl,16
		mov     al,ah
		shr     al,2
		sub     dl,al
		mov     [di+1],dl
		mov     dl,63
		mov     al,ah
		shr     al,2
		sub     dl,al
		mov     [di+2],dl
		add     ah,bl
		cmp     ah,64
		jb      GPCont
		neg     bl
		add     ah,bl
		add     ah,bl
GPCont:         add     di,3
		loop    GPLoop

		mov     [Fade],0                ; setup variables.
		mov     [EscKey],0
		mov     [Timer],0
		mov     [RandSeed],SEED

		mov     [HWavPos1],0            ; setup wave parameters.
		mov     [HWavPos2],0
		mov     [VWavPos1],0
		mov     [VWavPos2],0
		mov     [HWavInc1],1
		mov     [VWavInc1],7

		mov     cx,MAXV                 ; use enough steps
SetupWaves:     push    cx                      ; to update all the
		call    UpdHWaves               ; waves entries.
		call    UpdVWaves
		pop     cx
		loop    SetupWaves


PlasmaLoop:     cmp     [EscKey],0              ; change fade level.
		jne     FadeOut
FadeIn:         mov     bl,[Fade]
		cmp     bl,64
		jae     SkipFade
		inc     [Fade]
		jmp     FadeInOut
FadeOut:        mov     bl,[Fade]
		cmp     bl,0
		jbe     FadeInOut
		dec     [Fade]

FadeInOut:      lea     si,[Palette]            ; set faded palette.
		lea     di,[FadePalette]
		mov     cx,768
		mov     ax,ds
		mov     es,ax
		cld
FadeLoop:       lodsb
		mul     bl
		shr     ax,6
		stosb
		loop    FadeLoop

DoFade:         lea     si,[FadePalette]        ; ensures thats always
		mov     cx,3*(MAXH+MAXVW+1)     ; waits the VR per frame.
		call    SetPalette
		jmp     DoPlasma

SkipFade:       call    WaitVRT

DoPlasma:       call    UpdHWaves               ; updates horiz waves.
		call    UpdVWaves               ; updates vert waves.
		call    UpdBmp                  ; updates bitmap.
		call    PutBmp                  ; draw plasma.

		call    Random                  ; change wave's speed.
		and     ax,7
		add     ax,3
		mov     [HWavInc1],ax
		call    Random
		and     ax,3
		add     ax,5
		mov     [VWavInc1],ax

		mov     ah,1                    ; if any key pressed,
		int     16h
		jz      CheckTimer
		mov     ah,0
		int     16h
		jmp     BeginFadeOut

CheckTimer:     inc     [Timer]                 ; or timeout,
		cmp     [Timer],TIMEOUT
		jb      CheckExit

BeginFadeOut:   inc     [EscKey]                ; then fade-out and exit.

CheckExit:      cmp     [Fade],0
		je      PlasmaExit
		jmp     PlasmaLoop

PlasmaExit:     mov     ax,0003h
		int     10h

		pop     es
		pop     ds
		popa
		ret

WavePlasma      endp

		end
;=============================================================================
; lenz.asm - Lenz or Crystal Ball Demostration.
;                                                    File created: 10/18/93
; Copyright (c) 1993, Carlos Hasan                  Last modified: 11/16/93
;
; Description:
;   This file implements a Lenz-like Crystall Ball effect using the
;   VGA 320x200x256 graphics mode and a 320x200x256 picture.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembled.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;
; Modifications:
;  10/22/93 - Startup Code and Picture/Palette in .OBJ files.
;  11/01/93 - Fixed Vertical Strengh Amplification.
;  11/16/93 - Added EmBoss and Slide Effect.
;=============================================================================

		jumps
		.model  small,pascal
		.286

		dosseg                          ; used to link like
		.stack  1024                    ; an standalone program.

		global  LenzDemo:proc
		global  LenzPal:byte            ; in LENZPAL.OBJ file.
		global  LenzPic:byte            ; in LENZRAW.OBJ file.

;========================= Demo equates ======================================
;
; Note: 1. Lenz strengh is computed like:  Strengh = 256/Factor
;          where Factor is the real amplification of the lenz.
;
;       2. I have used a picture with a gray scale palette at
;          entries from 128 to 255. Emboss Bright, Depth, MinGray
;          and MaxGray must be adjusted for others pictures.
;

RADIUS          equ     52                      ; Lenz Radius in pixels.
RADIUSI         equ     (15*RADIUS)/20          ; Internal Lenz Radius.
STRENGH         equ     155                     ; Lenz Amplify (fixed 8.8).
MAXWIDTH        equ     320                     ; VGA 320x200x256 dimensions.
MAXHEIGHT       equ     200
SEED            equ     286Ah                   ; Random seed for movement.
BRIGHT          equ     150                     ; Emboss Bright Factor.
DEPTH           equ     12*256                  ; Emboss Depth Factor (8.8).
MINGRAY         equ     128                     ; Emboss Min/Max Gray
MAXGRAY         equ     255                     ; Scale Range Values.
TIMEOUT         equ     70 * 6                  ; at least 6 secs.

;======================== Demo data ==========================================

		.data

LenzTable       dw      4*RADIUS*RADIUS dup(?)  ; Holds the transformation.
LenzWidth       dw      2*RADIUS dup(?)         ; Scanline widths.
RandSeed        dw      ?                       ; Random Seed.
Timer           dw      ?                       ; Timer counter.

;======================== Demo Routines ======================================

		.code

;-----------------------------------------------------------------------------
; Random - Returns a random number of 16 bits, modified version of the
;  ripped System unit random routine of the Borland Pascal 7.0.
; Out:
;  AX - random value.
; Modified:
;  AX, DX, Flags.
;-----------------------------------------------------------------------------

Random          proc near

		mov     ax,[RandSeed]
		mov     dx,8405h
		mul     dx
		inc     ax
		mov     [RandSeed],ax
		ret

Random          endp

;-----------------------------------------------------------------------------
; WaitVRT - Waits the next VGA Vertical Retrace Period.
;-----------------------------------------------------------------------------

WaitVRT         proc near

		mov     dx,3DAh
WaitVR1:        in      al,dx
		test    al,8
		jne     WaitVR1
WaitVR2:        in      al,dx
		test    al,8
		je      WaitVR2
		ret

WaitVRT         endp

;-----------------------------------------------------------------------------
; Delay - Sleeps during any amount of time. Uses the VGA Vertical retrace.
; In:
;   CX - Number of ticks to speed (ticks at 70Hz).
;-----------------------------------------------------------------------------

Delay           proc near

DelayLoop:      call    WaitVRT
		loop    DelayLoop
		ret

Delay           endp

;-----------------------------------------------------------------------------
; SetPalette - Sets the VGA color palette.
; In:
;   ES:SI - Palette segment address.
;-----------------------------------------------------------------------------

SetPalette      proc near

		push    ds
		mov     ax,es
		mov     ds,ax
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		inc     dx
		mov     cx,768
		cld
		rep     outsb
		pop     ds
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; ShowSpray - Writes a picture on the scren using a Spray-like effect.
; In:
;   DX - Picture source segment.
;-----------------------------------------------------------------------------

ShowSpray       proc near

		push    ds
		push    es

		mov     ds,dx
		xor     si,si
		mov     ax,0A000h
		mov     es,ax

		xor     cx,cx
SprayLoop:      push    cx
		xor     bx,bx
SprayLine:      push    bx
		mov     ah,cs:[RandTable+bx]
		mov     bx,cx
		mov     al,cs:[RandTable+bx]
		mov     bx,ax
		mov     di,ax
		mov     al,ds:[si+bx]
		mov     es:[di],al
		pop     bx
		inc     cl
		inc     bl
		jne     SprayLine
		pop     cx
		inc     cl
		jne     SprayLoop

		pop     es
		pop     ds
		ret

RandTable label byte
      db   83,   8,  18, 177,  13, 241, 149, 157
      db   75, 248, 254,  23,  16,  66, 207,  31
      db  211, 183,  80, 242, 218,  27,  15, 128
      db   94,  98,   4,  36, 139, 110,  85, 230
      db  212,  26,  12, 249, 169, 233, 200, 150
      db   95, 114, 130, 167, 202, 187,  76, 145
      db   62, 117, 115, 190, 209,  42, 185, 224
      db  129, 104, 108, 192, 174, 137,  44,  41
      db  141,  53, 179,  81, 181,  57, 147, 210
      db   50, 134, 156, 125, 133, 126, 106, 162
      db   20,  59,  84,   0, 151, 143, 101, 215
      db   68, 246, 189, 197,  99, 213, 112, 144
      db   28, 235, 240,  90, 154,  56, 138, 165
      db   19, 166, 159,  92, 127, 208, 105, 118
      db  119, 153, 191, 184,  87,  70,   9, 164
      db   60, 252,  96,   3, 171,  38, 136,  14
      db    7, 160,  71, 146, 102, 229, 227,  43
      db  221, 182, 217,  30, 131, 219,  61, 180
      db  195, 245, 109, 203,  24,  49, 170, 247
      db   46, 148, 122, 250, 173, 107, 255, 194
      db    6,  37,  93,  22, 168,  97, 193,   5
      db   51, 223, 116,  86,   1,  89, 121, 243
      db  140, 220,  39, 222,  65,  55,  17,  54
      db  175, 206, 214, 155, 142, 163,  25, 188
      db  178,  11, 204, 135, 201, 238,  79, 132
      db  198,  40,  21,  45, 237, 253, 152,  74
      db   32, 111,  52,  47, 236,   2, 176, 239
      db  234,  58, 100,  91, 172,  73,  82, 205
      db   34,  88,  78, 231, 232, 225,  48, 251
      db   67, 123, 244,  29, 216,  64, 196,  69
      db  199,  33,  72,  35,  10,  63, 161, 228
      db  113, 158, 120, 103, 124, 186, 226,  77

ShowSpray     endp

;-----------------------------------------------------------------------------
; DoEmBoss - Do the EmBoss effect into a 320x200x256 picture.
; In:
;  DX - Picture Source Segment.
;-----------------------------------------------------------------------------

DoEmboss        proc

		pusha
		push    ds

		mov     ds,dx                   ; DS:SI = source image.
		xor     si,si
		xor     cx,cx
EmBossLine:     push    cx                      ; Y= 0..198
		xor     bx,bx
EmBossLoop:     push    bx                      ; X= 0..318
		add     bx,cx
		xor     dh,dh
		mov     dl,[si+bx]
		mov     ax,dx
		mov     dl,[si+bx+MAXWIDTH+1]
		sub     ax,dx
		mov     dx,DEPTH                ; EmBoss Depth Factor.
		imul    dx
		mov     al,ah
		mov     ah,dl
		add     ax,BRIGHT
		cmp     ax,MINGRAY              ; Check Color Range.
		jge     EmbossHigh
		mov     ax,MINGRAY
EmbossHigh:     cmp     ax,MAXGRAY
		jle     EmbossLow
		mov     ax,MAXGRAY
EmbossLow:      mov     [si+bx],al
		pop     bx
		inc     bx
		cmp     bx,MAXWIDTH-2
		jbe     EmbossLoop
		pop     cx
		add     cx,MAXWIDTH
		cmp     cx,MAXWIDTH*(MAXHEIGHT-2)
		jbe     EmbossLine

		pop     ds
		popa
		ret

DoEmboss        endp

;-----------------------------------------------------------------------------
; ShowSlide - Shows a 320x200x256 picture using a Slide Effect.
; In:
;  DX - Piccy Source Segment.
;-----------------------------------------------------------------------------

ShowSlide       proc
		local    Level:word:MAXWIDTH,Weight:word:MAXWIDTH,\
		   LevelPtr:word,WeightPtr:word

		pusha
		push    ds
		push    es

		mov     ds,dx           ; DS:SI = Source Picture.
		xor     si,si

		mov     ax,ss
		mov     es,ax

		lea     di,[Level]      ; Clear Slide Row Levels.
		mov     cx,MAXWIDTH
		cld
		xor     ax,ax
		rep     stosw

		lea     di,[Weight]     ; Clear Slide Row Weights.
		mov     cx,MAXWIDTH
		cld
		xor     ax,ax
		rep     stosw

		mov     ax,0A000h
		mov     es,ax

SlideLoop:      call    WaitVRT
		lea     bx,[Level]      ; Loads Level Pointer.
		mov     [LevelPtr],bx

		lea     bx,[Weight]     ; Loads Weight Pointer.
		mov     [WeightPtr],bx

		xor     cx,cx           ; For Each Column:
		xor     dx,dx

SlideInner:     mov     bx,[LevelPtr]   ; Level[Col] < 320*200? Skip.
		mov     ax,ss:[bx]
		cmp     ax,MAXWIDTH*MAXHEIGHT
		jae     SlideContinue

		inc     dx              ; Sets Flag.

		mov     bx,[WeightPtr]  ; Weight[Col] <> 0?
		mov     ax,ss:[bx]      ; Yes, Decrease.
		test    ax,ax           ; No, Slide Down Row.
		jz      SlideDown
		dec     ax
		mov     ss:[bx],ax
		jmp     SlideContinue

SlideDown:      mov     bx,[LevelPtr]   ; Level[Col] += 320
		mov     ax,ss:[bx]
		add     ax,MAXWIDTH
		mov     ss:[bx],ax
		add     ax,cx           ; DI = Col + Level[Col]
		mov     di,ax
		mov     bx,di           ; Sets New Row Weight:
		mov     al,es:[di+MAXWIDTH] ; W=ABS(VMEM[DI+320]-VMEM[DI])
		sub     al,es:[di]
		jge     SlidePos
		neg     al
SlidePos:       xor     ah,ah
		mov     bx,[WeightPtr]
		mov     ss:[bx],ax

		mov     bx,di           ; Put Pixel at (Col,Level[Col])
		mov     al,ds:[si+bx]
		mov     es:[di],al

SlideContinue:  add     [LevelPtr],2    ; Next Column.
		add     [WeightPtr],2
		inc     cx
		cmp     cx,MAXWIDTH
		jb      SlideInner

		test    dx,dx           ; Screen 100% filled?
		jnz     SlideLoop       ; No, Repeat.

		pop     es
		pop     ds
		popa
		ret

ShowSlide       endp


;-----------------------------------------------------------------------------
; GenLenz - Renders the Transformation matrix used during animation.
;
; Note: The square root is calculated using the Newton iteration
;       aproximation algorithm:
;                                        y + (r - x)
;               y  r - x     y  
;                                             2y
;
;       We performs only one iteration using a initial y value
;       near to the real square root wanted.
;-----------------------------------------------------------------------------

GenLenz         proc near
		local    X:word,Y:word,R:word,Dist:Word,AddX:word,AddY:word

		mov      ax,ds
		mov      es,ax
		cld

		xor      ax,ax                  ; Fills the whole rectangle
		lea      di,[LenzTable]         ; matrix with a linear
		mov      cx,2*RADIUS            ; transformation.
MakLinLoop:     push     ax
		push     cx
		mov      cx,2*RADIUS
MakLinRow:      stosw
		inc      ax
		loop     MakLinRow
		pop      cx
		pop      ax
		add      ax,MAXWIDTH
		loop     MakLinLoop

		mov      [X],RADIUS             ; makes the scanlines
		mov      [Y],0                  ; widths of the lenz
MakWidth:       cmp      [Y],RADIUS             ; with radius RADIUS.
		jge      MakXWidth
		mov      ax,[X]
		mov      bx,RADIUS              ; LenzWidth[Radius+Y] = X
		add      bx,[Y]
		shl      bx,1
		mov      [LenzWidth+bx],ax
		mov      bx,RADIUS              ; LenzWidth[Radius-Y-1] = X
		sub      bx,[Y]
		dec      bx
		shl      bx,1
		mov      [LenzWidth+bx],ax
		mov      ax,[Y]                 ; X = Radius - Y
		imul     ax
		mov      bx,ax
		mov      ax,[X]
		imul     ax
		sub      ax,bx
		add      ax,RADIUS*RADIUS
		sar      ax,1
		cwd
		mov      bx,[X]
		idiv     bx
		mov      [X],ax
		inc      [Y]                    ; Y = Y+1
		jmp      MakWidth
MakXWidth:


		mov     [X],RADIUSI             ; Makes the transformation
		mov     [Y],0                   ; for the Lenz of radius
MakLoop:        cmp     [Y],RADIUSI             ; RADIUSY. Notice that
		jge     MakExit                 ; this lets a border
						; used for restoring the
						; background while moving
						; the lenz into the screen.

		mov     ax,[X]                  ; compute the scanline
		mov     dx,6                    ; width adjusting with
		imul    dx                      ; an aspect ratio of 6/5.
		mov     bx,5
		idiv    bx
		mov     [R],ax

		mov     [Dist],0
		mov     [AddX],0
		mov     [AddY],ax

MakLine:        mov     ax,[R]
		cmp     [AddX],ax
		jge     MakLineBreak

		; si = @LenzTable[0,RADIUS-Y-1]

		lea     si,[LenzTable]
		mov     ax,RADIUS
		sub     ax,[Y]
		dec     ax
		imul    ax,2*RADIUS
		add     si,ax
		shl     si,1

		; di = @LenzTable[0,RADIUS+Y]

		lea     di,[LenzTable]
		mov     ax,RADIUS
		add     ax,[Y]
		imul    ax,2*RADIUS
		add     di,ax
		shl     di,1

		; Lenz[RADIUS+AddX,RADIUS-Y-1] = RADIUS+Hi(Dist) +
		;     MAXWIDTH * (RADIUS-1-STRENGH*Y)

		mov     bx,RADIUS
		add     bx,[AddX]
		shl     bx,1
		mov     ax,[Y]
		imul    ax,STRENGH
		sar     ax,8
		imul    ax,MAXWIDTH
		neg     ax
		add     ax,RADIUS+MAXWIDTH*(RADIUS-1)
		mov     dx,[Dist]
		shr     dx,8
		add     ax,dx
		mov     [si+bx],ax

		; Lenz[RADIUS-AddX-1,RADIUS-Y-1] = RADIUS-Hi(Dist)-1+
		;     MAXWIDTH * (RADIUS-1-STRENGH*Y)

		mov     bx,RADIUS
		sub     bx,[AddX]
		dec     bx
		shl     bx,1
		mov     ax,[Y]
		imul    ax,STRENGH
		sar     ax,8
		imul    ax,MAXWIDTH
		neg     ax
		add     ax,RADIUS+MAXWIDTH*(RADIUS-1)
		mov     dx,[Dist]
		shr     dx,8
		sub     ax,dx
		dec     ax
		mov     [si+bx],ax

		; LenzTable[RADIUS+AddX,RADIUS+Y] = RADIUS+Hi(Dist)+
		;    MAXWIDTH * (RADIUS + STRENGH*Y)

		mov     bx,RADIUS
		add     bx,[AddX]
		shl     bx,1
		mov     ax,[Y]
		imul    ax,STRENGH
		sar     ax,8
		imul    ax,MAXWIDTH
		add     ax,RADIUS+MAXWIDTH*RADIUS
		mov     dx,[Dist]
		shr     dx,8
		add     ax,dx
		mov     [di+bx],ax

		; LenzTable[RADIUS-AddX-1,RADIUS+Y] = RADIUS-Hi(Dist)-1+
		;    MAXWIDTH * (RADIUS+STRENGH*Y)

		mov     bx,RADIUS
		sub     bx,[AddX]
		dec     bx
		shl     bx,1
		mov     ax,[Y]
		imul    ax,STRENGH
		sar     ax,8
		imul    ax,MAXWIDTH
		add     ax,RADIUS+MAXWIDTH*RADIUS
		mov     dx,[Dist]
		shr     dx,8
		sub     ax,dx
		dec     ax
		mov     [di+bx],ax

		; Dist = Dist + (Strengh*Radius)/dY

		mov     ax,STRENGH*RADIUS
		cwd
		mov     bx,[AddY]
		idiv    bx
		add     [Dist],ax

		mov     ax,[AddY]               ; dY = R - dX
		imul    ax
		mov     bx,ax
		mov     ax,[AddX]
		imul    ax
		sub     bx,ax
		mov     ax,[R]
		imul    ax
		add     ax,bx
		sar     ax,1
		cwd
		mov     bx,[AddY]
		idiv    bx
		mov     [AddY],ax
		inc     [AddX]                  ; dX = dX+1
		jmp     MakLine

MakLineBreak:   mov     ax,[X]                  ; X = Radius' - Y
		imul    ax
		mov     bx,ax
		mov     ax,[Y]
		imul    ax
		sub     bx,ax
		mov     ax,RADIUSI*RADIUSI
		add     ax,bx
		sar     ax,1
		cwd
		mov     bx,[X]
		idiv    bx
		mov     [X],ax
		inc     [Y]                     ; Y = Y+1
		jmp     MakLoop
MakExit:        ret

GenLenz         endp

;-----------------------------------------------------------------------------
; WriteLenz - Writes the Lenz using the transformation matrix.
; In:
;  DI  - Starting offset location of the lenz.
;  DX  - Virtual picture used like background.
;-----------------------------------------------------------------------------

WriteLenz       proc near

		push    bp
		mov     ax,0A000h
		mov     es,ax
		lea     bx,[LenzTable]
		lea     si,[LenzWidth]
		mov     bp,di
		mov     cx,2*RADIUS
		cld
WriteLoop:      push    bx
		push    cx
		push    si
		push    di
		cmp     di,MAXWIDTH*MAXHEIGHT
		jae     WriteBreak
		mov     cx,[si]                 ; gets the scanline width.
		mov     ax,RADIUS
		sub     ax,cx
		add     di,ax
		add     bx,ax
		add     bx,ax
WriteLine:      push    es
		mov     es,dx
		mov     si,[bx]
		mov     al,es:[bp+si]
		mov     si,[bx+2]
		mov     ah,es:[bp+si]
		add     bx,4
		pop     es
		stosw
		loop    WriteLine
WriteBreak:     pop     di
		pop     si
		pop     cx
		pop     bx
		add     bx,4*RADIUS
		add     si,2
		add     di,MAXWIDTH
		loop    WriteLoop
		pop     bp
		ret

WriteLenz       endp


;-----------------------------------------------------------------------------
; LenzDemo - Performs the demostration.
; In:
;   DS      - Data Segment.
;   PicSeg  - VGA 320x200x256 Picture used for Background.
;   PalSeg  - Color Palette of the Picture.
;-----------------------------------------------------------------------------

LenzDemo        proc  PicSeg:word,PalSeg:dword
		local   X:word,Y:word,AddX:word,AddY:word

		mov     ax,13h                  ; sets 320x200x256 mode.
		int     10h

		call    GenLenz                 ; creates the lenz matrix.

		mov     cx,35                   ; waits 0.5 seconds.
		call    Delay

		les     si,[PalSeg]             ; sets the palette.
		call    SetPalette

		mov     dx,[PicSeg]             ; writes the picture
		call    ShowSpray               ; to the screen.

		mov     [RandSeed],SEED         ; Randomize.
		mov     [Timer],0

		mov     [X],RADIUS
		mov     [Y],RADIUS
		mov     [AddX],3
		mov     [AddY],2

DemoLoop:       call    WaitVRT                 ; Waits VR period.

		mov     ax,[Y]                  ; outputs the lenz
		sub     ax,RADIUS               ; crystall ball at
		mov     dx,MAXWIDTH             ; center coordinates (X,Y).
		mul     dx
		add     ax,[X]
		sub     ax,RADIUS
		mov     di,ax
		mov     dx,[PicSeg]
		call    WriteLenz

AdjustX:        mov     ax,[X]                  ; adjust the X coord.
		add     ax,[AddX]
		cmp     ax,RADIUS
		jb      ChangeX
		cmp     ax,MAXWIDTH-RADIUS
		ja      ChangeX
		mov     [X],ax
		jmp     AdjustY
ChangeX:        call    Random
		shr     ax,15
		inc     ax
		cmp     [AddX],0
		jl      SetAddX
		neg     ax
SetAddX:        mov     [AddX],ax

AdjustY:        mov     ax,[Y]                  ; adjust the Y coord.
		add     ax,[AddY]
		cmp     ax,RADIUSI
		jb      ChangeY
		cmp     ax,MAXHEIGHT-RADIUSI
		ja      ChangeY
		mov     [Y],ax
		jmp     Continue
ChangeY:        call    Random
		and     ax,1
		inc     ax
		cmp     [AddY],0
		jl      SetAddY
		neg     ax
SetAddY:        mov     [AddY],ax

Continue:       inc     [Timer]                 ; timeout?
		cmp     [Timer],TIMEOUT
		jae     DemoExit

		mov     ah,1                    ; any key pressed?
		int     16h
		je      DemoLoop
		mov     ah,0                    ; flush keyboard.
		int     16h
		
DemoExit:       mov     dx,[PicSeg]             ; EmBoss the Piccy.
		call    DoEmboss

		mov     dx,[PicSeg]             ; SlideDown the Piccy.
		call    ShowSlide

		mov     cx,70                   ; Sleep a while..
		call    Delay

		mov     es,[PicSeg]             ; Blanks the picture.
		xor     di,di
		mov     cx,MAXWIDTH*MAXHEIGHT
		xor     ax,ax
		cld
		rep     stosb

		mov     dx,[PicSeg]             ; Clears the Screen.
		call    ShowSpray

		mov     cx,35                   ; waits 0.5 seconds.
		call    Delay

		mov     ax,03h                  ; restores 80x25x16 mode.
		int     10h
		ret

LenzDemo        endp


;-----------------------------------------------------------------------------
; Start - Startup Code called from DOS.
; In:
;   ES - Program Segment Prefix.
;-----------------------------------------------------------------------------

Start           proc

		mov     ax,@Data
		mov     ds,ax
		call    LenzDemo,SEG LenzPic,SEG LenzPal,OFFSET LenzPal
		mov     ax,4C00h
		int     21h

Start           endp

		end     Start
;=============================================================================
; dblscrl.asm - Double Horizontal Scroller.
;                                                   File created: 11/21/93
; Copyright (c) 1993, Carlos Hasan                 Last modified: 11/21/93
;
; Description:
;  Another Horizontal Scroller using a Logo Picture of 256x128x256.
;
; Dependency:
;  Requires Turbo Assembler 3.2 or later to be assembled.
;  Dependant on the IBM PC 286 or better processor.
;=============================================================================

	ideal
	model   small,pascal
	jumps
	p286

	dosseg
	stack   1024
	ends

	global  LogoRAW:byte            ; LOGO.RAW linked file.
	global  LogoPAL:byte            ; LOGO.PAL linked file.

;=========================== Data Segment ====================================

	dataseg

SCREENWIDTH     equ  (2*320)            ; Logical Screen Width
					; Enough Space for Double-Window
LOGOWIDTH       equ  256                ; Logo Piccy Dimensions.
LOGOHEIGHT      equ  128
SCROLLSPEED     equ  2                  ; Scrollers Speed.

;=========================== Code Segment ====================================

	codeseg

;-----------------------------------------------------------------------------
; SetModeX - Sets the VGA in Tweaked ModeX 320x400x256.
;-----------------------------------------------------------------------------

proc    SetModeX
	mov     ax,0013h                ; Sets VGA linear 320x200x256
	int     10h
	mov     dx,3C4h                 ; Disable Chain-Four
	mov     ax,0604h
	out     dx,ax
	mov     dx,3C4h                 ; Enable Write to All Four Planes
	mov     ax,0F02h
	out     dx,ax
	mov     ax,0A000h               ; Clear Display Memory
	mov     es,ax
	xor     di,di
	xor     ax,ax
	mov     cx,8000h
	cld
	rep     stosw
	mov     dx,3D4h                 ; Reprogram CRT Controller:
	mov     ax,00014h               ; turn off dword mode
	out     dx,ax
	mov     ax,0e317h               ; turn on byte mode
	out     dx,ax
	mov     ax,00009h               ; cell height
	out     dx,ax
	mov     dx,3D4h                 ; Sets Logical Screen Width
	mov     al,13h
	mov     ah,SCREENWIDTH/8
	out     dx,ax
	ret
endp    SetModeX

;-----------------------------------------------------------------------------
; SetStartAddr - Sets the VGA Start Address Register.
; In:
;  BX = Start Address.
;-----------------------------------------------------------------------------

proc    SetStartAddr
	mov     dx,3D4h                 ; Sets VGA Start Address
	mov     al,0Dh
	mov     ah,bl
	out     dx,ax
	dec     al
	mov     ah,bh
	out     dx,ax
	ret
endp    SetStartAddr

;-----------------------------------------------------------------------------
; WaitVR - Waits the Next VGA Vertical Retrace Ending.
;-----------------------------------------------------------------------------

proc    WaitVR
	mov     dx,3DAh
WaitStartVR:
	in      al,dx
	test    al,8
	je      WaitStartVR
WaitEndVR:
	in      al,dx
	test    al,8
	jne     WaitEndVR
	ret
endp    WaitVR

;-----------------------------------------------------------------------------
; DrawLogo - Writes on Screen the Logo Picture.
;-----------------------------------------------------------------------------

proc    DrawLogo
	pusha
	push    ds
	push    es
	call    WaitVR
	mov     ax,SEG LogoPAL          ; Sets the Logo Palette
	mov     ds,ax
	mov     si,OFFSET LogoPAL
	mov     cx,768
	mov     dx,3C8h
	xor     al,al
	out     dx,al
	inc     dx
	rep     outsb
	mov     ax,SEG LogoRAW          ; Load LogoRAW Address
	mov     ds,ax
	mov     si,OFFSET LogoRAW
	mov     ax,0A000h               ; Load Display Memory Segment
	mov     es,ax
	mov     ax,1102h
DrawPlanes:
	push    ax
	push    si
	mov     dx,3C4h                 ; Select Write Plane
	out     dx,ax
	mov     di,(320+SCREENWIDTH*220)/4
	mov     bx,LOGOHEIGHT           ; Write Pixels
DrawLoop:
	mov     cx,LOGOWIDTH/4
DrawRow:
	mov     al,[ds:si]
	mov     [es:di],al
	add     si,4
	inc     di
	loop    DrawRow
	add     di,(SCREENWIDTH-LOGOWIDTH)/4
	dec     bx
	jne     DrawLoop
	pop     si
	pop     ax
	inc     si
	add     ah,ah                   ; Next Plane.
	jnc     DrawPlanes
	pop     es
	pop     ds
	popa
	ret
endp    DrawLogo

;-----------------------------------------------------------------------------
; Start - Start the Demostration. Called from DOS.
;-----------------------------------------------------------------------------

proc    Start
	mov     ax,@Data                ; Sets Data Segment.
	mov     ds,ax
	mov     bx,sp                   ; Shrink Program Memory Block.
	shr     bx,4
	inc     bx
	mov     ax,ss
	mov     dx,es
	sub     ax,dx
	add     bx,ax
	mov     ah,4Ah
	int     21h
	call    SetModeX                ; Sets VGA ModeX.
	call    DrawLogo                ; Draw Logo.
	mov     cx,35                   ; Sleep about 0.5 sec
SleepEntry:
	call    WaitVR
	loop    SleepEntry
	mov     si,0                    ; Starting Scrollers
	mov     di,SCREENWIDTH*164/4    ; Address Offsets.
DemoLoop:
	call    WaitVR                  ; Waits Vertical Retrace.
	mov     bx,si                   ; Show Upper Scroller.
	call    SetStartAddr
	call    WaitVR                  ; Waits Vertical Retrace.
	mov     bx,di                   ; Show Bottom Scroller
	call    SetStartAddr
	add     si,SCROLLSPEED          ; Move Scrollers to the Left&Right.
	sub     di,SCROLLSPEED
	cmp     si,SCREENWIDTH/4        ; Enough Frames?
	jbe     DemoLoop
DemoExit:
	mov     cx,35                   ; Sleep about 0.5 sec
SleepExit:
	call    WaitVR
	loop    SleepExit
	mov     ax,0003h                ; Set Text Mode.
	int     10h
	mov     ax,4C00h                ; Exit to DOS.
	int     21h
endp    Start

	end     Start
;=============================================================================
; land.asm - Landscape fractal demostration.
;                                                    File created:  9/30/93
; Copyright (c) 1993, Carlos Hasan                  Last modified: 10/22/93
;
; Description:
;   This file implements a fractal 3D landscape rotation using the basic
;   plasma routines and 3D rotations. This uses the VGA 320x200x256 mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembled.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;
; Modifications:
;  10/22/93  - Startup Code. Now is an Standalone Program.
;=============================================================================

		.model  small,pascal
		.286

		dosseg                          ; used to link like
		.stack  1024                    ; an standalone program.

		global  DrawPlasma:proc         ; in PLASMA.ASM file.
		global  LandScape:proc

;===================== Demo equates and data =================================

TIMEOUT         equ     70 * 10                 ; about 10 sec for timeout.
FADESPEED       equ     6                       ; fade speed.
SCREENWIDTH     equ     320                     ; screen dimensions.
SCREENHEIGHT    equ     200
TRIGSHIFT       equ     6                       ; sin/cos shift factor.
LANDSCAPEX      equ     320                     ; landscape grid dimensions.
LANDSCAPEY      equ     200
WATERLEVEL      equ     128                     ; plasma water level.
PLASMASEED      equ     8945h                   ; plasma random seed.
CENTERX         equ     160                     ; screen grid center
CENTERY         equ     140                     ; position.
GRIDX           equ     32                      ; screen grid dimensions
GRIDY           equ     32                      ; and gaps length.
GRIDDX          equ     6
GRIDDY          equ     6

		.data

		include sincos.inc              ; sinus/cosinus table.

LandSeg         dw      ?                       ; landscape levels.
Pixels          dw      GRIDX * GRIDY dup (?)   ; screen pixels locations.
Palette         db      768 dup (?)             ; hold the color palette.
FromPalette     db      768 dup (?)             ; fading-palettes.
ToPalette       db      768 dup (?)
Timer           dw      ?                       ; timer counter.

;======================= Demo routines =======================================

		.code

;-----------------------------------------------------------------------------
; WaitVRT - Waits the VGA vertical retrace period.
;-----------------------------------------------------------------------------

WaitVRT         proc near

		mov     dx,3DAh
WaitVRT1:       in      al,dx                   ; wait the start of
		test    al,8                    ; vertical retrace.
		jz      WaitVRT1
WaitVRT2:       in      al,dx                   ; wait the end of
		test    al,8                    ; vertical retrace.
		jnz     WaitVRT2
		ret

WaitVRT         endp

;-----------------------------------------------------------------------------
; SetPalette - set the 256 entries of the VGA color palette.
; In:
;   DS:SI - Palette structure address.
;-----------------------------------------------------------------------------

SetPalette      proc near

		mov     cx,768
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		call    WaitVRT
		mov     dx,3C9h
		rep     outsb
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; FadeTo - Fade palette effect.
; In:
;  FromPalette - Source palette.
;  ToPalette   - Destination palette.
;-----------------------------------------------------------------------------

FadeTo         proc near

FadeLoop:       lea     si,[FromPalette]
		call    SetPalette
		mov     cx,768
		xor     dx,dx
		xor     bx,bx
FadeColor:      mov     al,[FromPalette+bx]
		mov     ah,[ToPalette+bx]
		cmp     al,ah
		je      SkipFade
		ja      FadeOut
FadeIn:         add     al,FADESPEED
		cmp     al,ah
		jl      SetColor
		mov     al,ah
		jmp     SetColor
FadeOut:        sub     al,FADESPEED
		cmp     al,ah
		jg      SetColor
		mov     al,ah
		jmp     SetColor
SetColor:       mov     [FromPalette+bx],al
		inc     dx
SkipFade:       inc     bx
		loop    FadeColor
		test    dx,dx
		jne     FadeLoop
		ret

FadeTo          endp

;-----------------------------------------------------------------------------
; FlashIn - Flash fade-in effect.
; In:
;  Palette - Source palette.
;-----------------------------------------------------------------------------

FlashIn         proc near

		mov     ax,ds
		mov     es,ax
		cld
		lea     di,[FromPalette]        ; fade from black to white.
		mov     cx,768
		mov     al,00h
		rep     stosb
		lea     di,[ToPalette]
		mov     cx,768
		mov     al,3Fh
		rep     stosb
		call    FadeTo
		lea     di,[FromPalette]        ; fade from white to
		mov     cx,768                  ; destination palette.
		mov     al,3Fh
		rep     stosb
		lea     si,[Palette]
		lea     di,[ToPalette]
		mov     cx,768
		rep     movsb
		call    FadeTo
		ret

FlashIn         endp

;-----------------------------------------------------------------------------
; FlashOut - Flash fade-out effect.
; In:
;  Palette - Source palette.
;-----------------------------------------------------------------------------

FlashOut        proc near

		mov     ax,ds
		mov     es,ax
		cld
		lea     di,[ToPalette]          ; fade from source palette
		mov     cx,768                  ; to white palette.
		mov     al,3Fh
		rep     stosb
		lea     si,[Palette]
		lea     di,[FromPalette]
		mov     cx,768
		rep     movsb
		call    FadeTo
		lea     di,[FromPalette]        ; fade from white to black.
		mov     cx,768
		mov     al,3Fh
		rep     stosb
		lea     di,[ToPalette]
		mov     cx,768
		mov     al,00h
		rep     stosb
		call    FadeTo
		ret

FlashOut        endp

;-----------------------------------------------------------------------------
; GenLandscape - This routines generates the lanscape surface using the
;   plasma routines basically and checks that all the mountain levels
;   are in the right range.
; In:
;  LandSeg - Segment addressing for the landscape.
;-----------------------------------------------------------------------------

GenLandscape    proc near

		mov     ax,[LandSeg]            ; clear landscape area.
		mov     es,ax
		xor     di,di
		xor     ax,ax
		mov     cx,LANDSCAPEX * LANDSCAPEY
		cld
		rep     stosb

		; draw initial plasma landscape.
		call    DrawPlasma,0,0,LANDSCAPEX-1,LANDSCAPEY-1, \
						 PLASMASEED,[LandSeg]

		; adjust levels for the real landscape.

		mov     ax,[LandSeg]
		mov     es,ax
		xor     di,di
		mov     cx,LANDSCAPEX * LANDSCAPEY
		cld
AdjLoop:        mov     al,es:[di]
		sub     al,WATERLEVEL
		test    al,al
		jge     AdjLevel
		xor     al,al
AdjLevel:       xor     ah,ah
		imul    ax,192
		inc     ah
		mov     es:[di],ah
		inc     di
		loop    AdjLoop
		ret

GenLandscape    endp


;-----------------------------------------------------------------------------
; DrawLandscape - Draws a region of the landscape on the screen starting
;   at the specified position and rotation angles. The clipping support
;   have been removed for speed.
; In:
;   (PosX,PosY) - Landscape starting position.
;   AngleY      - Inclination angle.
;   AngleZ      - Spin angle.
;-----------------------------------------------------------------------------

DrawLandscape   proc near PosX:word,PosY:word, AngleY:word,AngleZ:word
		local SinY:word,SinZ:word,CosY:word,CosZ:word, \
		      YIAdd:word,YJAdd:word,ZIAdd:word,ZJAdd:word, \
		      Y0:word,Z0:word,Y:word,Z:word

		mov     bx,[AngleY]             ; compute rotation
		mov     al,[SinTable+bx]        ; parameters.
		cbw
		mov     [SinY],ax
		mov     al,[CosTable+bx]
		cbw
		mov     [CosY],ax

		mov     bx,[AngleZ]
		mov     al,[SinTable+bx]
		cbw
		mov     [SinZ],ax
		mov     al,[CosTable+bx]
		cbw
		mov     [CosZ],ax

		mov     ax,[SinZ]               ; yiadd = griddx * sinz
		imul    ax,GRIDDX
		mov     [YIAdd],ax
		mov     ax,[CosZ]               ; yjadd = griddy * cosz
		imul    ax,GRIDDY
		mov     [YJAdd],ax
		mov     ax,[CosZ]               ; ziadd = griddx * cosz * siny
		mov     dx,[SinY]
		imul    dx
		imul    ax,GRIDDX
		sar     ax,TRIGSHIFT
		mov     [ZIAdd],ax
		mov     ax,[SinZ]               ; zjadd = -griddy * sinz * siny
		mov     dx,[SinY]
		imul    dx
		imul    ax,-GRIDDY
		sar     ax,TRIGSHIFT
		mov     [ZJAdd],ax

		mov     ax,[YIAdd]              ; compute starting grid
		imul    ax,-GRIDX/2             ; corner position.
		mov     dx,[YJAdd]
		imul    dx,-GRIDY/2
		add     ax,dx
		mov     [Y0],ax
		mov     ax,[ZIAdd]
		imul    ax,-GRIDX/2
		mov     dx,[ZJAdd]
		imul    dx,-GRIDY/2
		add     ax,dx
		mov     [Z0],ax

		mov     ax,[LandSeg]            ; es = landscape segment.
		mov     es,ax

		lea     si,[Pixels]             ; ds:si = pixels offsets.

		mov     di,[PosY]               ; store offset
		imul    di,LANDSCAPEX           ; just for speed.
		add     di,[PosX]

		mov     cx,GRIDX
ForI:           push    cx
		mov     ax,[Y0]                 ; y = y0
		mov     [Y],ax
		mov     ax,[Z0]                 ; z = z0
		mov     [Z],ax

		mov     cx,GRIDY
ForJ:           push    es
		mov     ax,0A000h               ; clear old pixel.
		mov     es,ax
		mov     bx,[si]
		mov     byte ptr es:[bx],al
		pop     es

; here the code must be hooked to support clipping, use an "illegal"
; offset to store pixels that are not drawed, and then the routine above
; must erase only "legal" pixels.

		mov     bl,es:[di]              ; bl = landscape(posx,posy)
		mov     al,bl                   ; ax = -centery + (z + bl*cosy)
		xor     ah,ah
		imul    [CosY]
		add     ax,[Z]
		sar     ax,TRIGSHIFT
		sub     ax,CENTERY
		imul    ax,SCREENWIDTH
		mov     dx,[Y]                  ; dx = centery + y
		sar     dx,TRIGSHIFT
		add     dx,CENTERX
		sub     dx,ax
		mov     [si],dx                 ; store pixel offset.

		push    es
		mov     ax,0A000h               ; paint new pixel.
		mov     es,ax
		xchg    dx,bx
		mov     es:[bx],dl
		pop     es

		mov     ax,[YJAdd]              ; y = y + yjadd
		add     [Y],ax
		mov     ax,[ZJAdd]              ; z = z + zjadd
		add     [Z],ax
		inc     di                      ; posy = posy + 1
		add     si,2
		loop    ForJ

		mov     ax,[YIAdd]              ; y0 = y0 + yiadd
		add     [Y0],ax
		mov     ax,[ZIAdd]              ; z0 = z0 + ziadd
		add     [Z0],ax
		add     di,LANDSCAPEX-GRIDY     ; posy = posy - gridy
		pop     cx                      ; posx = posx + 1
		loop    ForI
		ret

DrawLandscape   endp

;-----------------------------------------------------------------------------
; LandScape - Main landscape demo routine. Because this routine was tested
;   using the Borland Pascal high-level interface, the allocation of the
;   memory is done by the caller.
; In:
;  DS     - Data segment.
;  MemSeg - Memory segment of 64K needed for storage.
;-----------------------------------------------------------------------------

LandScape       proc    MemSeg:word
		local   PosX:word,PosY:word,AngleY:word,AngleZ:word

		mov     ax,0013h                ; set VGA 320x200x256 mode.
		int     10h

		mov     ax,[MemSeg]             ; setup landscape
		mov     [LandSeg],ax            ; memory segment.

		lea     di,[Palette]            ; set black palette.
		mov     ax,ds
		mov     es,ax
		mov     cx,768
		xor     ax,ax
		cld
		rep     stosb
		lea     si,[Palette]
		call    SetPalette

GenPalette:     lea     di,[Palette]            ; generate color palette.
		mov     ax,3F00h
		mov     [di+0],al               ; background.
		mov     [di+1],al
		mov     [di+2],al
		add     di,3
		mov     [di+0],al               ; blue. (water)
		mov     [di+1],al
		mov     [di+2],ah
		add     di,3
		mov     ax,0000h                ; green to brown.
		mov     bx,3F00h
		mov     dx,0000h
		mov     cx,61
GP0:            mov     [di+0],ah
		mov     [di+1],bh
		mov     [di+2],dh
		add     di,3
		add     ax,0108h
		sub     bx,0086h
		add     dx,0000h
		loop    GP0
		mov     ax,3F00h                ; brown to white.
		mov     bx,2000h                ; (mountain)
		mov     dx,0000h
		mov     cx,48
GP1:            mov     [di+0],ah
		mov     [di+1],bh
		mov     [di+2],dh
		add     di,3
		add     ax,0000h
		add     bx,00AAh
		add     dx,0150h
		loop    GP1
		mov     ax,3F00h                ; white. (snow)
		mov     bx,3F00h
		mov     dx,3F00h
		mov     cx,145
GP2:            mov     [di+0],ah
		mov     [di+1],bh
		mov     [di+2],dh
		add     di,3
		add     ax,0000h
		add     bx,0000h
		add     dx,0000h
		loop    GP2

		call    GenLandscape            ; creates the landscape.

		mov     [AngleY],240            ; inclination angle.
		mov     [AngleZ],0              ; initial spin angle.
		mov     [PosX],0                ; starting landscape
		mov     [PosY],0                ; position.

		; pixels offset array could be cleaned but not necesary,
		; because i am using the 64K of video memory ...
		; i can't overwrite anything! :-)

		; draw hidden landscape and do flash-in effect.

		call    DrawLandscape,[PosX],[PosY],[AngleY],[AngleZ]
		lea     si,[Palette]
		call    FlashIn

		mov     [Timer],0               ; set timer counter.

		mov     si,1                    ; starting landscape
		mov     di,1                    ; directions.

LandLoop:       call    WaitVRT                 ; wait vertical retrace.

		push    si                      ; draw landscape.
		push    di
		call    DrawLandscape,[PosX],[PosY],[AngleY],[AngleZ]
		pop     di
		pop     si

		inc     byte ptr [AngleZ]       ; increase spin angle.
		add     [PosX],si               ; advance landscape position.
		add     [PosY],di
TestX:          cmp     [PosX],0                ; check for boundaries.
		jl      NegIncX
		cmp     [PosX],LANDSCAPEX-GRIDX
		jl      TestY
NegIncX:        sub     [PosX],si
		neg     si
TestY:          cmp     [PosY],0
		jl      NegIncY
		cmp     [PosY],LANDSCAPEY-GRIDY
		jl      CheckExit
NegIncY:        sub     [PosY],di
		neg     di

CheckExit:      inc     [Timer]                 ; timeout?
		cmp     [Timer],TIMEOUT
		jae     ByeBye

		mov     ah,1                    ; any key pressed?
		int     16h
		jz      LandLoop

ByeBye:         call    FlashOut                ; flash-out!

		mov     ax,03h                  ; set 80x25x16 text mode.
		int     10h
		ret

LandScape       endp


;-----------------------------------------------------------------------------
; Start - Startup code called from DOS.
; In:
;   ES - Program Segment Prefix.
;-----------------------------------------------------------------------------

Start           proc

		mov     ax,@Data
		mov     ds,ax

		mov     ax,ss                   ; shrink memory block.
		mov     bx,es
		sub     ax,bx
		mov     bx,sp
		shr     bx,4
		inc     bx
		add     bx,ax
		mov     ah,4Ah
		int     21h

		mov     ah,48h                  ; allocate 64000 bytes.
		mov     bx,4000
		int     21h
		jc      Exit
		push    ax
		call    LandScape,ax            ; do demostration.
		pop     es
		mov     ah,49h                  ; free 64000 bytes.
		int     21h

Exit:           mov     ax,4C00h                ; exit to DOS.
		int     21h

Start           endp

		end     Start
;=============================================================================
; shades.asm - Bop Shades Demostration.
;                                                    File created: 10-21-93
; Copyright (c) 1993, Carlos Hasan                  Last modified: 10-21-93
;
; Description:
;   This code implements bop shades using a gray palette of 64 levels in
;   the VGA 320x200x256 graphics mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembled.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;=============================================================================

		jumps
		.model  small,pascal
		.286

		dosseg                          ; used for linking like 
		.stack 1024                     ; an Standalone program.

		global  BopShades:proc

;======================== Demo Equates and Data ==============================

TIMEOUT         equ     4000                    ; Number of Frames Total.
MAXWIDTH        equ     320                     ; Screen Dimens.
MAXHEIGHT       equ     200
CENTERX         equ     160-25                  ; Screen Center Coord.
CENTERY         equ     100-25
MAXBOPS         equ     150                     ; Number of Bops.
RADIUSX         equ     120                     ; Bops Path Radius.
RADIUSY         equ     60

		.data

		include shades.inc              ; Bop Points Table.
		include sincos.inc              ; Sin/Cos Table.

BopQueue        dw      MAXBOPS dup(?)          ; Bops Positions Queue.
BopHead         dw      ?                       ; Current Queue Head.
Angle           dw      ?                       ; Bops Path Generation
Phase1          dw      ?                       ; Parameters.
Phase2          dw      ?                       ; Angle, Phase, Incs.
PhInc1          dw      ?
PhInc2          dw      ?
Frames          dw      ?                       ; Frame Counter.

;======================== Demo Routines ======================================

		.code

;-----------------------------------------------------------------------------
; ShowBop - Shows a BopShade at specified position.
; In:
;   DI  - Position Offset.
;-----------------------------------------------------------------------------

ShowBop         proc near

		mov     ax,0A000h
		mov     es,ax
		xor     si,si
		mov     cx,BOPPTS
ShowLoop:       mov     al,[BopAddTab+si]
		shl     si,1
		mov     bx,[BopTab+si]
		shr     si,1
		add     es:[bx+di],al
		inc     si
		loop    ShowLoop
		ret

ShowBop         endp

;-----------------------------------------------------------------------------
; HideBop - Hides a BopShade at specified position.
; In:
;   DI  - Position Offset.
;-----------------------------------------------------------------------------

HideBop         proc near

		mov     ax,0A000h
		mov     es,ax
		xor     si,si
		mov     cx,BOPPTS
HideLoop:       mov     al,[BopAddTab+si]
		shl     si,1
		mov     bx,[BopTab+si]
		shr     si,1
		sub     es:[bx+di],al
		inc     si
		loop    HideLoop
		ret

HideBop         endp

;-----------------------------------------------------------------------------
; InitBops - Initializes the BopShade Queue.
;-----------------------------------------------------------------------------

InitBops        proc near

		mov     ax,ds
		mov     es,ax
		lea     di,[BopQueue]
		mov     cx,MAXBOPS
		mov     ax,0FFFFh               ; illegel offset,
		cld                             ; because first bops
		rep     stosw                   ; are hidden.
		mov     [BopHead],0
		ret

InitBops        endp

;-----------------------------------------------------------------------------
; PutBop - Puts a new BopShade onto the Queue and updates the screen.
; In:
;   (CX,DX) - Screen coordinates.
;-----------------------------------------------------------------------------

PutBop          proc near

		mov     di,dx
		imul    di,MAXWIDTH
		add     di,cx
		mov     bx,[BopHead]
		xchg    [BopQueue+bx],di
		cmp     di,MAXWIDTH*MAXHEIGHT
		jae     PutNewBop
		call    HideBop
PutNewBop:      mov     bx,[BopHead]
		mov     di,[BopQueue+bx]
		cmp     di,MAXWIDTH*MAXHEIGHT
		jae     SkipShow
		call    ShowBop
SkipShow:       add     [BopHead],2
		cmp     [BopHead],2*MAXBOPS
		jb      ByePutBop
		mov     [BopHead],0
ByePutBop:      ret

PutBop          endp


;-----------------------------------------------------------------------------
; BopShades - Performs the Demostration.
; In:
;   DS - Data Segment.
;-----------------------------------------------------------------------------

BopShades       proc

		mov     ax,13h                  ; Sets 320x200x256 mode.
		int     10h

		mov     dx,3C8h                 ; Set the Shaded Palette.
		xor     al,al
		out     dx,al
		inc     dx
		mov     cx,256
		xor     ah,ah
SetPal:         xor     al,al
		out     dx,al
		out     dx,al
		mov     al,ah
		out     dx,al
		cmp     ah,63
		jae     SetBrk
		inc     ah
SetBrk:         loop    SetPal

		call    InitBops                ; Init BopsQueue.

		mov     [Angle],0               ; Init Variables.
		mov     [Phase1],2*1024
		mov     [Phase2],2*1024
		mov     [PhInc1],2
		mov     [PhInc2],3
		mov     [Frames],0

ShadesLoop:     mov     ax,[Angle]              ; Compute X Coord.
		imul    [Phase1]
		mov     bl,ah
		mov     bh,dl
		shr     bx,2
		xor     bh,bh
		mov     al,[CosTable+bx]
		mov     ah,RADIUSX
		imul    ah
		sar     ax,6
		add     ax,CENTERX
		mov     cx,ax

		mov     ax,[Angle]              ; Compute Y Coord.
		imul    [Phase2]
		mov     bl,ah
		mov     bh,dl
		shr     bx,2
		xor     bh,bh
		mov     al,[SinTable+bx]
		mov     ah,RADIUSY
		imul    ah
		sar     ax,6
		add     ax,CENTERY
		mov     dx,ax

		call    PutBop                  ; Puts BopShade at (CX,DX)

		mov     ax,[Angle]              ; Increment Angle.
		inc     ax
		and     ax,1023
		mov     [Angle],ax

		mov     ax,[Phase1]             ; Increment Phase1.
		add     ax,[PhInc1]
		cwd
		mov     bx,5*1024
		div     bx
		mov     [Phase1],dx

		mov     ax,[Phase2]             ; Increment Phase2.
		add     ax,[PhInc2]
		cwd
		mov     bx,5*1024
		div     bx
		mov     [Phase2],dx

		inc     [Frames]                ; enough frames showed?
		cmp     [Frames],TIMEOUT
		ja      ShadesBye

		mov     ah,1                    ; any key pressed?
		int     16h
		je      ShadesLoop

ShadesBye:      
		mov     cx,MAXBOPS              ; Hides all the Bops.
HidesLoop:      push    cx
		mov     cx,0FFFFh
		mov     dx,cx
		call    PutBop
		pop     cx
		loop    HidesLoop

		mov     ax,03h
		int     10h
		ret

BopShades       endp


;-----------------------------------------------------------------------------
; Start - Startup Code called from DOS.
; In:
;   DS - Program Segment Prefix.
;-----------------------------------------------------------------------------

Start           proc

		mov     ax,@Data
		mov     ds,ax
		call    BopShades
		mov     ax,4C00h
		int     21h

Start           endp

		end     Start
;=============================================================================
; worm.asm - Worm Hole palette demostration.
;                                                    File created: 10/04/93
; Copyright (c) 1993, Carlos Hasan                  Last modified: 10/04/93
;
; Description:
;   This file demostrates a palette animation routine, the main piccy
; was created using the pascal source file. This one uses the VGA card
; in 320x200x256 graphics mode.
;
; Portability:
;  Requires Turbo Assembler 3.2 or better to be assembled.
;  Dependent on the IBM PC 286 and the VGA graphics card.
;
; Modifications:
;  10/22/93 - Startup Code and Picture on .OBJ file.
;=============================================================================

		.model  small,pascal
		.286

		dosseg                          ; used to link like
		.stack  1024                    ; and standalone program.

		global  WormHole:proc
		global  WormPic:byte            ; in WORMRAW.OBJ file.

;====================== Demo Equates and Data ================================

TIMEOUT         equ     70 * 8                  ; About 8 sec for timeout.

		.data

Palette         db      768 dup (?)             ; hold the color palette
FadePalette     db      768 dup (?)             ; and the faded palette.
Timer           dw      ?                       ; timer counter.

;========================== Demo routines ====================================

		.code

;-----------------------------------------------------------------------------
; SetPalette - set the 256 entries of the VGA color palette.
; In:
;   DS:SI - Palette structure address.
;-----------------------------------------------------------------------------

SetPalette      proc near

		mov     cx,768
		mov     dx,3C8h
		xor     al,al
		out     dx,al
		mov     dx,3DAh
WaitVRT1:       in      al,dx                   ; wait the start of
		test    al,8                    ; vertical retrace.
		jz      WaitVRT1
WaitVRT2:       in      al,dx                   ; wait the end of
		test    al,8                    ; vertical retrace.
		jnz     WaitVRT2
		mov     dx,3C9h
		rep     outsb
		ret

SetPalette      endp

;-----------------------------------------------------------------------------
; RotPalette - Rotates the palette and do fading.
; In:
;   Palette - Source palette.
;   Fade    - Fading level.
;-----------------------------------------------------------------------------

RotPalette      proc near Fade:word

		mov     ax,ds
		mov     es,ax

		lea     di,[FadePalette]
		mov     cx,16*3
		xor     ax,ax
		cld
		rep     stosb
		lea     si,[Palette+32*3]
		mov     cx,224*3
		cld
		rep     movsb
		lea     si,[Palette+16*3]
		mov     cx,16*3
		rep     movsb

		lea     bx,[FadePalette]
		mov     cx,16
RotLoop:        push    cx
		mov     si,bx
		mov     di,bx
		lodsb
		mov     ah,al
		lodsb
		mov     dl,al
		lodsb
		mov     dh,al
		mov     cx,15*3
		rep     movsb
		mov     al,ah
		stosb
		mov     al,dl
		stosb
		mov     al,dh
		stosb
		add     bx,16*3
		pop     cx
		loop    RotLoop

		lea     si,[FadePalette]
		lea     di,[Palette]
		mov     cx,768
		rep     movsb

		lea     si,[FadePalette]
		mov     cx,768
		mov     dx,[Fade]
FadeLoop:       mov     al,[si]
		mul     dl
		shr     ax,7
		mov     [si],al
		inc     si
		loop    FadeLoop

		lea     si,[FadePalette]
		call    SetPalette
		ret

RotPalette      endp

;-----------------------------------------------------------------------------
; WormHole - Worm Hole demostration.
; In:
;   DS     - Data segment.
;   PicSeg - 320x200x256 picture segment address.
;-----------------------------------------------------------------------------

WormHole        proc    PicPtr:dword
		local   Fade:word

		mov     ax,0013h                ; set 320x200x256 mode.
		int     10h

		mov     ax,ds                   ; set black palette.
		mov     es,ax
		lea     di,[Palette]
		mov     cx,768
		xor     ax,ax
		cld
		rep     stosb
		lea     si,[Palette]
		call    SetPalette

		lea     di,[Palette]            ; generate the palette.
		mov     cx,256
		xor     bx,bx
GenPalette:     mov     ax,bx
		shr     ax,4
		and     ax,0Fh
		shl     ax,2
		mov     [di+0],al
		mov     ax,bx
		and     ax,0Fh
		shl     ax,1
		mov     [di+1],al
		mov     al,3Fh
		mov     [di+2],al
		add     di,3
		inc     bx
		loop    GenPalette

		push    ds                      ; write the picture.
		mov     ax,0A000h
		mov     es,ax
		lds     si,[PicPtr]
		xor     di,di
		mov     cx,320*200
		cld
		rep     movsb
		pop     ds

		mov     [Fade],0
		mov     [Timer],0

WormIn:         call    RotPalette,[Fade]       ; rotate palette.
		cmp     [Fade],128              ; adjust fade level.
		jae     WormTime
		inc     [Fade]
WormTime:       inc     [Timer]                 ; check if timeout,
		cmp     [Timer],TIMEOUT
		jae     WormOut
WormKey:        mov     ah,1                    ; or any key pressed.
		int     16h
		jz      WormIn

WormOut:        cmp     [Fade],128              ; start fading-out.
		ja      WormExit
		call    RotPalette,[Fade]
		dec     [Fade]
		jmp     WormOut

WormExit:       mov     ax,03h                  ; restore 80x25x16 textmode.
		int     10h
		ret

WormHole        endp

;-----------------------------------------------------------------------------
; Start - Startup Code called from DOS.
; In:
;   ES - Program Segment Prefix.
;-----------------------------------------------------------------------------

Start           proc

		mov     ax,@Data
		mov     ds,ax
		call    WormHole,SEG WormPic,OFFSET WormPic
		mov     ax,4C00h
		int     21h

Start           endp

		end     Start
;=============================================================================
; txtfx.asm - Texture Effect Demostration.
;                                                    File created: 11/03/93
; Copyright (c) 1993, Carlos Hasan                  Last modified: 11/04/93
;
; Description:
;   This file implements a texture algorithm that maps repeteadly into
; screen a picture of 128x128x256 using the tweaked 80x200x256 mode.
;
; Portability:
;   Requires Turbo Assembler 3.2 or better to be assembled.
;   Dependent on the IBM PC 286 and the VGA graphics card.
;=============================================================================

	ideal
	model   small,pascal
	jumps
	p286
	
	dosseg                  ; Used for Standalone DOS programs.
	stack   1024            ; Sets the Stack with 1KB of space.
	ends                    ; Must close stack segment!

;===================== External Data =========================================

	global  PicRaw:far      ; 128x128x256 Image.
	global  PicPal:far      ; RGB Image Palette.
	global  TextFx:proc

;===================== Demo Equates ==========================================

	dataseg

MAXWIDTH        equ     80      ; Screen Dimensions.
MAXHEIGHT       equ     200
BMPHEIGHT       equ     128     ; Image Bitmap Dimensions.
BMPWIDTH        equ     128
BMPMASK         equ     3FFFh   ; Image Position Mask.
TIMEOUT         equ     1800    ; Max Number of Frames for TimeOut.
ROTSPEED        equ     2       ; Rotation Speed Factor.
AMPSPEED        equ     4       ; Amplify Speed Factor.
FADESPEED       equ     6       ; Fadeout Speed Factor.

	include "SinCos.Inc"    ; Sinus/Cosinus Table.

;======================== Demo Routines ======================================

	codeseg

;-----------------------------------------------------------------------------
; SetGraphMode - Sets the tweaked 80x200x256 VGA mode.
;-----------------------------------------------------------------------------

proc    SetGraphMode
	mov     ax,13h          ; Sets VGA 320x200x256 mode.
	int     10h
	mov     dx,3C4h         ; Disable Chain-Four.
	mov     al,04h
	out     dx,al
	inc     dx
	in      al,dx
	and     al,0F7h
	out     dx,al
	mov     dx,3C4h         ; Enable All Planes.
	mov     ax,0F02h
	out     dx,ax
	mov     ax,0A000h       ; Clear Video Memory
	mov     es,ax
	xor     di,di
	xor     ax,ax
	mov     cx,8000h
	cld
	rep     stosw
	mov     dx,3D4h         ; Normal Word Addressing.
	mov     al,14h
	out     dx,al
	inc     dx
	in      al,dx
	and     al,0BFh
	out     dx,al
	dec     dx              ; Address Output Byte Mode.
	mov     al,17h
	out     dx,al
	inc     dx
	in      al,dx
	or      al,40h
	out     dx,al
	ret
endp    SetGraphMode


;-----------------------------------------------------------------------------
; SetTextMode - Restores 80x25x16 text mode.
;-----------------------------------------------------------------------------

proc    SetTextMode
	mov     ax,03h
	int     10h
	ret
endp    SetTextMode

;-----------------------------------------------------------------------------
; WaitVR - Waits the Next Vertical Retrace.
;-----------------------------------------------------------------------------

proc    WaitVR
	mov     dx,3DAh
WaitNotVRT:
	in      al,dx
	test    al,8
	jne     WaitNotVRT
WaitEndVRT:
	in      al,dx
	test    al,8
	je      WaitEndVRT
	ret
endp    WaitVR

;-----------------------------------------------------------------------------
; SetPalette - Sets the current VGA color palette.
; In:
;  DS:SI - Palette Address.
;-----------------------------------------------------------------------------

proc    SetPalette
	call    WaitVR
	mov     dx,3C8h
	xor     al,al
	out     dx,al
	inc     dx
	mov     cx,768
	cld
	rep     outsb
	ret
endp    SetPalette

;-----------------------------------------------------------------------------
; FadeOut - Fades out the RGB Palette.
; In:
;  DS:SI = Palette Address.
;-----------------------------------------------------------------------------

proc    FadeOut
	push    si
	push    ds
	mov     cx,768
	xor     bx,bx
	mov     di,si
DecPal: sub     [byte ptr di],FADESPEED
	jnc     NotDec
	inc     bx
	mov     [byte ptr di],0
NotDec: inc     di
	loop    DecPal
	push    bx
	call    SetPalette
	pop     bx
	pop     ds
	pop     si
	cmp     bx,768
	jb      FadeOut
	ret
endp    FadeOut

;-----------------------------------------------------------------------------
; RotImage - Puts on the screen the rotated image.
; In:
;  DeltaX,DeltaY = Rotation Parameters.
;  Image         = Source 128x128x256 Image Bitmap.
;-----------------------------------------------------------------------------

proc    RotImage DeltaX:word,DeltaY:word,Image:word
local   AddX:word:MAXWIDTH,AddY:word:MAXHEIGHT

	push    ds
	push    es

	shl     [DeltaX],1      ; Makes the Horiz Array
	shl     [DeltaY],1      ; of increments for the
	mov     cx,MAXWIDTH     ; Rotation.
	xor     bl,bl
	xor     dl,dl
	lea     di,[AddX]
MakeAddX:
	xor     bh,bh
	xor     dh,dh
	add     bx,[DeltaX]
	add     dx,[DeltaY]
	mov     al,dh
	cbw
	imul    si,ax,BMPWIDTH
	mov     al,bh
	cbw
	add     ax,si
	mov     [ss:di],ax
	add     di,2
	loop    MakeAddX

	sar     [DeltaX],1      ; Makes the Vert Array
	sar     [DeltaY],1      ; of increments for the
	mov     cx,MAXHEIGHT    ; Rotation.
	xor     bl,bl
	xor     dl,dl
	lea     di,[AddY]
MakeAddY:
	xor     bh,bh
	xor     dh,dh
	sub     bx,[DeltaY]
	add     dx,[DeltaX]
	mov     al,dh
	cbw
	imul    si,ax,BMPWIDTH
	mov     al,bh
	cbw
	add     ax,si
	mov     [ss:di],ax
	add     di,2
	loop    MakeAddY

	mov     ax,0A000h       ; Start drawing at the top left
	mov     es,ax           ; screen corner.
	xor     di,di
	mov     ds,[Image]      ; Load Source Image Address.
	xor     si,si
	mov     dx,BMPMASK      ; Load Image Position Mask.
	lea     bx,[AddY]
	mov     cx,MAXHEIGHT
	cld
DrawScanLines:
	push    si
	OFF=0                    ; This Loop have been unrolled
	REPT MAXWIDTH/2          ; for fastest drawing.
	and      si,dx           ; Also, the drawwing is done 
	mov      al,[si]         ; putting two pixels at once.
	add      si,[ss:AddX+OFF]
	and      si,dx
	mov      ah,[si]
	add      si,[ss:AddX+OFF+2]
	stosw
	OFF=OFF+4
	ENDM
	pop     si
	add     si,[ss:bx]       ; Next Scan Line. 
	add     bx,2
	dec     cx
	jne     DrawScanLines
	pop     es
	pop     ds
	ret
endp    RotImage

;-----------------------------------------------------------------------------
; TextFx - Performs the Demostration.
; In:
;  DS      = Data Segment.
;  Image   = Source Image Segment.
;  Palette = Image RGB Palette.
;-----------------------------------------------------------------------------

proc    TextFx Image:word,Palette:dword
	pusha
	push    ds
	push    es
	call    SetGraphMode    ; Init Graphics Mode.
	push    ds
	lds     si,[Palette]    ; Sets the RGB Palette.
	call    SetPalette
	pop     ds

	xor     bx,bx           ; Init Rotation Angle.
	mov     dx,32           ; Init Amplify Factor.
TextFxLoop:
	add     bl,ROTSPEED     ; Increase Rot Angle.
	add     dx,AMPSPEED     ; Increase Amplify Factor.
	mov     cl,[SinTable+bx]
	mov     ch,[CosTable+bx]
	push    bx
	push    dx
	mov     al,cl           ; Amplify Rotation Parameters
	cbw                     ; using the Amplify Factor.
	imul    dx
	mov     al,ah
	mov     ah,dl
	mov     bx,ax
	pop     dx
	push    dx
	mov     al,ch
	cbw
	imul    dx
	mov     al,ah
	mov     ah,dl
	call    RotImage,ax,bx,[Image]
	mov     ah,1            ; Any Key Pressed?
	int     16h
	pop     dx
	pop     bx
	jz      CheckTimeOut
	mov     ah,0
	int     16h
	jmp     TextExit
CheckTimeout:
	cmp     dx,TIMEOUT      ; Enough Frames Showed?
	jb      TextFxLoop
TextExit:
	lds     si,[Palette]    ; Fade out the Palette.
	call    FadeOut
	call    SetTextMode     ; Restores 80x25x16 Text Mode.
	pop     es
	pop     ds
	popa
	ret
endp    TextFx

;-----------------------------------------------------------------------------
; Start - Startup code called from DOS.
; In:
;  ES = Program Segment Prefix.
;-----------------------------------------------------------------------------

proc    Start
	mov     ax,@Data        ; Setup Data Segment.
	mov     ds,ax           ; Do the Demostration.
	call    TextFx,SEG PicRaw,SEG PicPal,OFFSET PicPal
	mov     ax,4C00h
	int     21h             ; Exit to DOS.
endp    Start

	end     Start
