; =========================================================
; = VESA - Intro                                          =
; =                                                       =
; = coded by zan in jan '96                               =
; =========================================================

.model tiny
.386
locals
.code

org 100h


; ---------------------------------------------------------
; Konstanten
; ---------------------------------------------------------
   stars           equ 300
   centerx         equ 320
   centery         equ 240
   centerxy        equ centerx shl 16+centery
   distancez       equ 200
   weiss           equ 255
   digitalxsize    equ  10
   digitalysize    equ  10
   digitalspace    equ   5


; ---------------------------------------------------------
; Hauptprogramm
; ---------------------------------------------------------
begin:
         cld                            ; go ahead, fred

         call cleardata                 ; COM-Datei wurde verkrzt, deshalb
                                        ; ist der Datenbereich in einem
                                        ; undefiniertem Zustand
         call check386                  ; min. 386er
         jc  ende

         call savepalette               ; Palette retten

         mov si,offset originalpalette  ; ausfaden
         call fadeout

         call initmode                  ; VESA-Mode 101h testen
         jc  ende

         call initdata                  ; Tabellen usw. initialisieren

         call palblack                  ; Palette schwarz
         call fillscreen                ; Hintergrund aufbauen

         mov ecx,190 shl 16+(centery-3*digitalysize)
         mov dx,64                      ; Telefonnummern Teil 1
         mov si,offset phonedigital1
         call digitaltext

         mov ecx,190 shl 16+(centery+digitalysize)
         mov si,offset phonedigital2	; Telefonnummern Teil 2
         call digitaltext


         mov si,offset newpalette       ; einfaden
         call fadein

@@angle:
         call showpoints                ; 3D-Feld anzeigen

         inc anglex                     ; Winkel ver„ndern
         inc angley
         inc anglez

         mov ah,1                       ; Tastaturstatus auslesen
         int 16h
         jnz @@raus                     ; Taste gedrckt ?

         call retrace                   ; Retrace abwarten

         jmp short @@angle              ; n„chstes Bild

@@raus:
         xor ah,ah                      ; Tastaturpuffer leeren
         int 16h

         mov si,offset newpalette
         call fadeout                   ; ausfaden

         mov ax,3                       ; in Textmodus schalten
         int 10h
         call palblack                  ; Palette vorsichtshalber schwarz

ende:
         mov ah,9                       ; Telefonnummern anzeigen
         mov dx,offset phonenumbers
         int 21h

         mov si,offset originalpalette  ; einfaden
         call fadein

         mov ah,4Ch                     ; Shutdown
         int 21h



; ---------------------------------------------------------
; CLEARDATA: fllt Datenbereich mit Nullen
; ---------------------------------------------------------
cleardata proc near
         push bx

         mov bx,offset endofzeros+1     ; Endelabel
         sub bx,offset startofzeros     ; Startlabel
@@data2zero:
         mov byte ptr startofzeros[bx],0; mit 0 berschreiben
         dec bx                         ; n„chstes Byte
         jnz @@data2zero                ; fertig ?

         pop bx
         ret
cleardata endp


; ---------------------------------------------------------
; CHECK386: testet auf 386 bzw. Nachfolger
; ---------------------------------------------------------
check386 proc near
         push ax

         xor ax,ax                      ; 0000hex pushen
         push ax
         popf                           ; als Flags laden
         pushf                          ; und wieder sichern
         pop ax                         ; in AX
         and ax,0F000h                  ; nur Bits 12 bis 15 interessant
         cmp ax,0F000h                  ; alle gesetzt ?
         je @@error			; ist 8086/8088/V20/V30

         mov ax,7000h                   ; 7000hex pushen
         push ax
         popf                           ; als Flags laden
         pushf                          ; und wieder sichern
         pop ax                         ; als AX wiederholen
         and ah,70h                     ; berprfen
         jz  @@error                    ; nicht ver„ndert => ist 286
         clc

         jmp short @@raus               ; Bereinigungcode ausfhren
@@error:
         mov ah,9                       ; god bless u
         mov dx,offset cpu386
         int 21h
         stc
@@raus:
         pop ax
         ret
check386 endp


; ---------------------------------------------------------
; INITMODE: initialisiert Mode 101h
; ---------------------------------------------------------
initmode proc near
         pushad

         push cs                        ; auf VESA-Treiber prfen
         pop es                         ; Segment der Tabelle laden
         mov di,offset infoblock        ; Offset laden
         mov ax,4F00h                   ; Info-Unterfunktion
         int 10h                        ; Interrupt aufrufen

         cmp ax,004Fh                   ; VESA vorhanden ? Test 1
         jne @@error
         cmp dword ptr infoblock[0],'ASEV'
         jne @@error                    ; VESA vorhanden ? Test 2

         mov ax,4F01h                   ; Modus 101h untersttzt ?
         mov cx,101h
         int 10h
         cmp ax,004Fh
         jne @@error

         mov eax,dword ptr infoblock[0Ch]
         or  eax,eax
         jz  @@error
         mov vesaptr,eax                ; FAR-CALL Zeiger

         mov ax,word ptr infoblock[4]   ; Granularit„t auf 64k testen
         cmp ax,64
         jne @@error

         mov ax,4F02h                   ; Modus einstellen
         mov bx,101h
         int 10h

         clc
         jmp short @@raus
@@error:
         mov ah,9                       ; omigod
         mov dx,offset problem
         int 21h
         stc
@@raus:
         popad
         ret
initmode endp


; ---------------------------------------------------------
; INITDATA: initialisiert alle Tabellen
; ---------------------------------------------------------
initdata proc near
         pushad

         xor ecx,ecx                    ; bei Y=0 anfangen
@@calc_yoffset:
         imul eax,ecx,640               ; Offset berechnen
         mov yoffset[bx],eax            ; und sichern
         add bx,4                       ; ist DWord = 4 Bytes
         inc cx                         ; n„chste Zeile
         cmp cx,479                     ; fertig ?
         jna @@calc_yoffset


         xor bx,bx                      ; Laufindex, bei 0 anfangen
@@randomize:
         call random                    ; Zufallsgenerator
         sar ah,1                       ; auf -63..+63 beschr„nken
         mov pointxtab[bx],ah           ; und sichern

         call random                    ; Zufallsgenerator
         sar ah,1                       ; auf -63..+63 beschr„nken
         mov pointytab[bx],ah           ; und sichern

         call random                    ; Zufallsgenerator
         sar ah,1                       ; auf -63..+63 beschr„nken
         mov pointztab[bx],ah           ; und sichern

         inc bx                         ; n„chster Punkt
         cmp bx,stars                   ; fertig ?
         jne @@randomize


         xor bx,bx                      ; wieder Laufindex
@@calc_cosinus:
         mov si,63                      ; Cosinus aus Sinus aufbauen
         sub si,bx                      ; 1.Quadrant Cosinus umgekehrt Sinus
         mov al,sinustab[si]
         mov cosinustab[bx],al
         neg al                         ; 256-Cosinus
         mov cosinus_3[bx],al           ; 3.Quadrant

         mov al,sinustab[bx]            ; Sinuswert laden
         mov cosinus_4[bx],al           ; 4.Quadrant Cosinus
         neg al                         ; 256-Sinus
         mov cosinus_2[bx],al           ; 2.Quadrant

         inc bl                         ; n„chster Winkel
         cmp bl,64                      ; fertig ?
         jne @@calc_cosinus


         xor bx,bx                      ; Palette aufbauen
         xor cl,cl
@@palette_loop1:
         mov newpalette[bx+2],cl        ; nur blau
         inc cl
         add bl,3
         cmp cl,64
         jne @@palette_loop1

         mov word ptr newpalette[3*255],63 shl 8+63
                                        ; weiá
         mov newpalette[3*255+2],63


         mov ax,0A000h                  ; ES ist immer 0A000h
         mov es,ax

         popad
         ret
initdata endp


; ---------------------------------------------------------
; SHOWPOINTS: zeichnet neues Bild
; ---------------------------------------------------------
showpoints proc near
         pushad

         xor bx,bx                      ; Laufindex Byte
         xor bp,bp                      ; Laufindex DWord
@@loop:
         mov dl,oldcolor[bx]            ; alte Farbe holen
         cmp dl,weiss                   ; doppelt gezeichnet ?
         je  @@doppelt
         mov ecx,screen2d[bp]           ; alten Koordinaten holen
         call putpixel

@@doppelt:
         mov al,pointxtab[bx]           ; Urpsrungskoordinaten holen
         mov ah,pointytab[bx]
         mov cl,pointztab[bx]

         movzx si,anglez                ; um Z-Achse drehen
         mov dl,sinustab[si]
         mov dh,cosinustab[si]
         call rotate

         xchg ah,cl
         movzx si,angley                ; um Y-Achse drehen
         mov dl,sinustab[si]
         mov dh,cosinustab[si]
         call rotate
         xchg ah,cl

         xchg al,cl
         movzx si,anglex                ; um X-Achse drehen
         mov dl,sinustab[si]
         mov dh,cosinustab[si]
         call rotate
         xchg al,cl

         movsx dx,cl                    ; auf 2D umrechnen
         movsx cx,al
         shl ecx,16
         movsx cx,ah
         call conv3d

         call setwindow
         mov dl,weiss                   ; weiáer Punkt
         xchg es:[di],dl
         mov oldcolor[bx],dl
         mov screen2d[bp],ecx           ; fr Wiederherstellung XY sichern

         add bp,4                       ; Laufindexe anpassen
         inc bx
         cmp bx,stars                   ; fertig ?
         jne @@loop

         popad
         ret
showpoints endp


; ---------------------------------------------------------
; CONV3D: konvertiert 3D-Koordinaten in 2D
; -> ECX  X,Y
; -> DX   Z
; <- ECX  X,Y der 2D-Form
; ---------------------------------------------------------
conv3d proc near
         push ax
         push bx
         push dx
         push si

         add dx,distancez-1             ; etwas Distanz zum Betrachter schaffen
         or  dx,dx                      ; Division durch 0 verhindern
         js  @@div0                     ; negatives Z, nicht sichtbar
         inc dx

         mov si,dx                      ; Z sichern

         mov ax,cx                      ; X holen
         shr ecx,16
         sal ax,8                       ; anpassen
         cwd                            ; DX mit Vorzeichen fllen
         idiv si                        ; durch Z dividieren
         mov bx,ax                      ; und sichern

         mov ax,cx                      ; Y holen
         sal ax,8                       ; anpassen
         cwd                            ; DX mit Vorzeichen fllen
         idiv si                        ; durch Z dividieren

         shrd ecx,eax,16                ; 2D-X in obere H„lfte von ECX
         mov cx,bx                      ; 2D-Y holen
         add ecx,centerxy               ; zentrieren
         jmp short @@nodiv0             ; Division-durch-0-Routine berspringen

@@div0:  mov ecx,640 shl 16+480         ; irgendein nicht sichtbarer Punkt
@@nodiv0:
         pop si
         pop dx
         pop bx
         pop ax
         ret
conv3d endp


; ---------------------------------------------------------
; ROTATE: rotiert um eine Achse
; -> AX  X,Y bzw. Z  (insgesamt 2 Werte)
; -> DL  Sinus
; -> DH  Cosinus
; <- AX  neue X,Y bzw. Z
; ---------------------------------------------------------
rotate proc near
         push cx
         push bx

         push ax

         mov bx,ax                      ; Xneu = X*cos-Y*sin
         imul dh
         mov cx,ax
         mov al,bh
         imul dl
         sub cx,ax

         pop ax
         imul dl                        ; Yneu = X*sin+Y*cos
         xchg bx,ax
         mov al,ah
         imul dh
         add ax,bx

         sal cx,1                       ; Xneu und Yneu runterrechnen, da
         sal ax,1                       ; Sinus und Cosinus -127..+127 statt
                                        ; -1..+1
         mov al,ch

         pop bx
         pop cx
         ret
rotate endp


; ---------------------------------------------------------
; SETWINDOW: setzt das Fenster im VRAM
; -> ECX  X,Y
; <- DI   Offset
; ---------------------------------------------------------
setwindow proc near
         push ax
         push bx
         push ecx
         push edx

         mov di,cx                      ; y holen
         shl di,2                       ; auf DWORD ausrichten
         mov edx,yoffset[di]            ; entsprechender 32-Bit-Offset

         shr ecx,16                     ; x addieren
         add edx,ecx

         mov di,dx                      ; in Granularit„tsoffset umrechnen

         shr edx,16                     ; Segmentanteil herausfiltern
         cmp dx,vesaseg
         je  @@ok
         mov vesaseg,dx
         xor bx,bx
         call dword ptr vesaptr         ; Window setzen
@@ok:
         pop edx
         pop ecx
         pop bx
         pop ax
         ret
setwindow endp


; ---------------------------------------------------------
; PUTPIXEL: setzt einen Punkt
; -> ECX   X,Y
; -> DL    Farbe
; ---------------------------------------------------------
putpixel proc near
         cmp cx,479                     ; Y vorzeichenlos ber 479 ?
         ja  @@do_not_set_any_pixel
         cmp ecx,640 shl 16             ; X vorzeichenlos ber 639 ?
         jae @@do_not_set_any_pixel

         call setwindow                 ; Window setzen
         mov es:[di],dl                 ; Punkt setzen

@@do_not_set_any_pixel:
         ret
putpixel endp


; ---------------------------------------------------------
; XLINE: zeichnet eine horizontale Linie
; -> ECX   X1,X2
; -> EDX   Y,Farbe
; ---------------------------------------------------------
xline proc near
         pushad

         mov bl,dl                      ; Farbe sichern
         shr edx,16                     ; Y holen
         mov bp,dx                      ; und sichern
         mov dh,bl                      ; Farbe zurck

         mov eax,ecx                    ; X1 holen
         shr eax,16
         mov bx,cx                      ; X2 holen

         shrd ecx,eax,16                ; Startpunkt checken
         mov cx,bp
         call setwindow
         cmp di,65535-640               ; Window-Break ?
         jae @@window_break

         sub bx,ax                      ; schnelle Variante
         inc bx
         mov cx,bx                      ; Anzahl Punkte in der Linie
         mov al,dh                      ; Farbe
         rep stosb                      ; ausgeben
         jmp short @@raus

@@window_break:
         shl ebx,16                     ; langsame Variante
@@loop:
         call setwindow                 ; („hnlich PUTPIXEL)
         mov es:[di],dh

         add ecx,10000h                 ; n„chstes X
         cmp ecx,ebx                    ; fertig ?
         jna @@loop

@@raus:
         popad
         ret
xline endp


; ---------------------------------------------------------
; YLINE: zeichnet eine vertikale Linie
; -> ECX   Y1,Y2
; -> EDX   X,Farbe
; ---------------------------------------------------------
yline proc near
         pushad

         mov bx,cx                      ; Y2 sichern
         shr ecx,16
         mov ax,cx                      ; Y1 sichern

         mov ecx,edx                    ; X setzen
         mov cx,ax                      ; Y1 setzen
@@loop:
         call setwindow                 ; Window anpassen
         mov es:[di],dl                 ; Punkt setzen
         inc cx                         ; n„chstes Y
         cmp cx,bx                      ; fertig ?
         jna @@loop

         popad
         ret
yline endp


; ---------------------------------------------------------
; FILLSCREEN: fllt den gesamten Bildschirm mit Farbverlauf
; ---------------------------------------------------------
fillscreen proc near
         pusha

         xor ax,ax
         xor edx,edx                    ; Farbe und Y setzen
         mov ecx,639                    ; X1 und X2 setzen
@@loop1:
         call xline                     ; Linie zeichnen
         inc al                         ; Farbe „ndern
         and al,3
         jnz @@dontinc1
         inc dl
@@dontinc1:
         add edx,10000h                 ; vorheriges Y
         cmp edx,240 shl 16
         jna @@loop1                    ; fertig ?

@@loop2:
         call xline                     ; Linie zeichnen
         inc al                         ; Farbe „ndern
         and al,3
         jnz @@dontinc2
         dec dl
@@dontinc2:
         add edx,10000h                 ; vorheriges Y
         cmp edx,480 shl 16
         jna @@loop2                    ; fertig ?

         popa
         ret
fillscreen endp


; ---------------------------------------------------------
; DIGITALCHAR: zeichnet ein Zeichen in Digitalschrift
; -> ECX   X,Y  (obere linke Ecke)
; ->  DH   DIGITAL-Code
; ->  DL   Farbe
; ---------------------------------------------------------
digitalchar proc near
         pushad

         mov ebp,ecx                    ; Koordinaten sichern

         mov ax,dx                      ; sichern

         mov si,0                       ; Laufindex
@@loop_xline:
         test ah,1                      ; unterstes Bit gel”scht ?
         jz  @@nix_xline

         mov ecx,ebp                    ; Koordinaten holen
         shr ecx,16                     ; X1 und X2 berechnen
         push cx
         inc cx
         shl ecx,16
         pop cx
         add cx,digitalxsize-1

         imul dx,si,digitalysize        ; Y berechnen
         add dx,bp
         shl edx,16
         mov dl,al                      ; Farbe holen

         call xline                     ; Linie zeichnen

         dec cx                         ; Parallelen zeichnen
         add ecx,10000h
         sub edx,10000h
         call xline
         add edx,20000h
         call xline

@@nix_xline:
         shr ah,1                       ; ein Bit weiterrcken
         inc si
         cmp si,2                       ; XLINEs fertig ?
         jna @@loop_xline


         mov si,0                       ; wieder Laufindex
@@loop_yline:
         test ah,1                      ; unterstes Bit testen
         jz  @@nix_yline

         mov cx,bp                      ; Y1 und Y2 berechnen
         inc cx
         shl ecx,16
         mov cx,bp
         add cx,digitalxsize-1

         imul dx,si,digitalysize        ; X berechnen
         mov edi,ebp
         shr edi,16
         add dx,di
         shl edx,16
         mov dl,al                      ; Farbe holen

         call yline                     ; Linie zeichnen

         dec cx                         ; Parallelen zeichnen
         add ecx,10000h
         sub edx,10000h
         call yline
         add edx,20000h
         call yline

@@nix_yline:
         shr ah,1                       ; ein Bit weiterrcken
         inc si
         cmp si,2                       ; 2.Y-Bit ?
         jne @@noinc
         add bp,digitalysize            ; jups, Y anpassen
         sub ebp,(2*digitalxsize) shl 16
@@noinc:
         cmp si,3                       ; fertig ?
         jna @@loop_yline

         popad
         ret
digitalchar endp


; ---------------------------------------------------------
; DIGITALTEXT: zeichnet eine Zeichenkette in Digitalschrift
; -> ECX   X,Y
; -> DL    Farbe
; -> SI    Offset des Textes
; ---------------------------------------------------------
digitaltext proc near
         pushad

@@loop:
         mov dh,[si]                    ; ein Zeichen holen
         cmp dh,'$'                     ; fertig ?
         je  @@fertig

         call digitalchar               ; Zeichen ausgeben
         inc si                         ; eins weiterrcken
         add ecx,(digitalxsize+digitalspace) shl 16
         jmp short @@loop               ; X anpassen, n„chstes Zeichen

@@fertig:
         popad
         ret
digitaltext endp


; ---------------------------------------------------------
; SAVEPALETTE: rettet die Originalpalette
; ---------------------------------------------------------
savepalette proc near
         pusha

         xor al,al
         mov dx,3C7h                    ; Read-Adress auf Farbe 0
         out dx,al
         add dl,2                       ; auf Data-Port weiter

         mov cx,3*256                   ; 3*256 Farben
         mov di,offset originalpalette  ; Tabelle bei CS:DI
         segcs rep insb                 ; los geht's

         popa
         ret
savepalette endp


; ---------------------------------------------------------
; SETPALETTE: setzt eine tempor„re Palette
; ---------------------------------------------------------
setpalette proc near
         pusha

         xor al,al                      ; bei Farbe 0 anfangen
         mov dx,3C8h
         out dx,al
         inc dx

         mov cx,3*256                   ; 3*256 Farben
         mov si,offset temppalette      ; Zeiger auf Tabelle
         segcs rep outsb                ; und setzen

         popa
         ret
setpalette endp


; ---------------------------------------------------------
; PALBLACK: setzt die komplette Palette auf schwarz
; ---------------------------------------------------------
palblack proc near
         pusha

         xor al,al                      ; bei Farbe 0 anfangen
         mov dx,3C8h
         out dx,al
         inc dx                         ; auf Datenport

         mov cx,3*256                   ; 768 Farbwerte
@@loop:
         out dx,al                      ; ausgeben
         loop @@loop

         popa
         ret
palblack endp


; ---------------------------------------------------------
; FADEIN: sanftes Einfaden der Palette
; -> SI   Offset der Tabelle
; ---------------------------------------------------------
fadein proc near
         pusha

         xor cl,cl                      ; 64 Abstufungen
@@frame_loop:
         xor bx,bx                      ; 3*256 Farben
@@color_loop:
         movzx ax,[bx+si]               ; Farbwert holen
         mul cl                         ; neu = alt*Stufe/64
         shr ax,6
         mov temppalette[bx],al

         inc bx                         ; n„chste Farbe
         cmp bx,3*256                   ; fertig ?
         jne @@color_loop

         call retrace                   ; synchronisieren
         call setpalette                ; ausgeben

         inc cl                         ; n„chste Stufe
         cmp cl,64
         jna @@frame_loop

         popa
         ret
fadein endp


; ---------------------------------------------------------
; FADEOUT: sanftes Ausfaden der Palette
; -> SI   Offset der Tabelle
; ---------------------------------------------------------
fadeout proc near
         pusha

         mov cl,64                      ; 64 Abstufungen
@@frame_loop:
         xor bx,bx                      ; 3*256 Farben
@@color_loop:
         movzx ax,[bx+si]               ; Farbwert holen
         mul cl                         ; neu = alt*Stufe/64
         shr ax,6
         mov temppalette[bx],al

         inc bx                         ; n„chste Farbe
         cmp bx,3*256                   ; fertig ?
         jne @@color_loop

         call retrace                   ; synchronisieren
         call setpalette                ; setzen

         dec cl                         ; n„chste Stufe
         jnz @@frame_loop

         popa
         ret
fadeout endp


; ---------------------------------------------------------
; RETRACE: wartet auf den vertikalen Retrace
; ---------------------------------------------------------
retrace proc near
         pusha

         mov dx,3DAh                    ; Portadresse
@@warte:
         in  al,dx                      ; Status lesen
         and al,8                       ; nur Bit 4 interessant
         jz @@warte                     ; wenn 0, dann warten

         popa
retrace endp


; ---------------------------------------------------------
; RANDOM: liefert eine WORD-Zufallszahl zurck
; <- AX
; ---------------------------------------------------------
random proc near
         push dx

         imul ax,randomseed,8405h       ; 16-Bit-Algorithmus
         inc ax                         ; biáchen zuf„lliger
         mov randomseed,ax              ; Startwert „ndern

         pop dx
         ret
random endp


; ---------------------------------------------------------
; Daten
; ---------------------------------------------------------
   problem         db 'Advanced VESA-videomode 101h not supported by your system.',10,13
                   db 'Just run a VESA-driver such as UNIVBE (especially Cirrus-Logic-cards).',10,13,'$'
   cpu386          db 'Sorry, you need at least a 386.',10,13,'$'
   phonenumbers    db 'This source is available at Ghost BBS.',9,9,9
                   db 'VESA iNTRO done by zï',10,13
                   db '   call now   +49-30-99400897',10,13
                   db '         or   +49-30-99400898',10,13,'$'
   phonedigital1   db 00101101b,01111011b,00101100b,00101100b,0 ; CALL
                   db 01111101b,01010111b,01111101b,00000010b   ; 030-
                   db 01011111b,01011111b,01011010b,01111101b   ; 9940
                   db 01111101b,01111111b,01011111b,01010001b   ; 0897
                   db '$'
   phonedigital2   db 0,01100110b,00100010b,0                   ; or
                   db 01111101b,01010111b,01111101b,00000010b   ; 030-
                   db 01011111b,01011111b,01011010b,01111101b   ; 9940
                   db 01111101b,01111111b,01011111b,01111111b   ; 0898
                   db '$'

   randomseed      dw 286Ah

   sinustab        db   2,  5,  8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47
                   db  50, 53, 56, 58, 61, 64, 67, 69, 72, 74, 77, 79, 82, 84, 86, 89
                   db  91, 93, 95, 97, 99,101,103,105,106,108,110,111,113,114,115,117
                   db 118,119,120,121,122,123,124,124,125,125,126,126,127,127,127,127

   startofzeros    label byte

   cosinustab      db 64 dup (0)
   cosinus_2       db 64 dup (0)
   cosinus_3       db 64 dup (0)
   cosinus_4       db 64 dup (0)

   infoblock       db 262 dup (0)
   vesaptr         dd 0
   vesaseg         dw 0

   anglex          db 0
   angley          db 0
   anglez          db 0
   pointxtab       db stars dup (0)
   pointytab       db stars dup (0)
   pointztab       db stars dup (0)
   screen2d        dd stars dup (0)
   oldcolor        db stars dup (0)

   newpalette      db 3*256 dup (0)
   originalpalette db 3*256 dup (0)
   temppalette     db 3*256 dup (0)

   yoffset         dd 480 dup (0)

   endofzeros      label byte

end begin