                          - SEPTIC'S DEMOSKOLA -

                                 Lektion 2
                                 ¯¯¯¯¯¯¯¯¯
                        Skriven av Vicious / Septic

                                 23 Apr 93



                                 Inledning
                                 ¯¯¯¯¯¯¯¯¯
Jaha, då var det dags för andra lektionen i demoskolan. Jag hoppas att
första delen inte vållade er några större problem. Om den gjorde det så var
inte rädda för att fråga mig! Jag svarar på allt, och jag kan även förklara
vissa "kod-tekniska" saker, för er som är assembler-nybörjare, bara ni
frågar...
  Tja, förra gången tog jag upp grunderna i copperns programmering. Jag
tänkte fortsätta med ett litet program som utnyttjar copperns möjligheter
att byta färger. Det är inte speciellt avancerat, men bör nog vara
intressant för nybörjaren, hoppas jag!


                                 Register
                                 ¯¯¯¯¯¯¯¯
Det enda nya registret jag behöver ta upp idag är VPOSR ($dff004). Det är,
precis som många andra register, ett READ ONLY register. Egentligen ligger
vertikala och horisontala positionen i registret VHPOSR ($dff006), där de
åtta lägsta bitarna är horis-positionen och de åtta högsta bitarna är
vert-positionen. Detta räcker ju dock inte på en PAL-amiga, eftersom vi
måste kunna vänta på positioner över $FF (vilket inte får plats i en byte),
men då hittar man högsta biten i VPOSR ($dff004).
  När man programmerar demos är det viktigt att kunna vänta på rasterstrålens
position för att undvika att ens rutiner flimmrar eller kanske till och med
försvinner ibland. Om man inte väntar på "syncen", som det kallas, så kan
rutiner också gå olika snabbt på olika datorer, och musikrutiner går
ALLDELES för fort. (Du kan ju testa att plocka bort hoppet till rutinen
SYNC i mainloopen på mitt program för att se skillnaden, och varför man bör
synca i sitt program...)
  Jaja, somliga brukar bara vänta på att vertikala positionen blir noll
genom den enkla testen:

WT:   TST.B   $DFF006
      BNE.S   WT

  Detta kan vara bra ibland, men oftast är det dumt. Runt den här
positionen, alltså vertikal-position noll, sker mycket uppdateringar,
coppern restartas och interrupt exekveras, vilket kan göra att vår rutin
fördröjs (om man har otur), och det är dessutom oflexibelt om man vill köra
en enkel liten bob längst upp på skärmen, för då kommer den inte att synas.
  Alltså, man bör kunna välja vilken vertikal position man vill vänta på,
och det är den metoden jag använder:

sync:   move.l  $dff004,d0      ; Här hämtar jag alltså både horisontell
                                ; och vertikal position, plus den mest
                                ; signifikanta biten av den vertikala
                                ; positionen och sen
        and.l   #$1ff00,d0      ; maskar jag bort, med kommandot AND, alla
                                ; onödiga bitar, alltså de horisontella,
                                ; eftersom jag bara kollar de vertikala.
        lsr.l   #8,d0           ; Sen gör jag en liten skift så att
                                ; vertikalpositionen hamnar längst ner i
                                ; wordet...
        cmp.w   #$f0,d0         ; Nu jämför jag det bara med den vertikala
                                ; position jag vill vänta på och
        bne.s   sync            ; hoppar tillbaks om det inte var rätt...

Resten av programmet ska inte innebära något nytt...Grunden är vårt förra
program, alltså den gamla startupen. Om du har glömt copperns instruktioner
kan du titta i lektion 1.
  Värt att notera kanske, är hur man stoppar en copperlista, dvs sätter den
i en evig loop. Det görs med två word så här:

   DC.W   $FFFF,$FFFE

Vad instruktionen egentligen gör är att vänta ovillkorligt på en position
som aldrig kommer att inträffa, och därför stannar coppern där tills den får
en signal att skärmen ska uppdateras igen, och då börjar den om från början
av listan.
  En annan intressant sak är hur man ska kunna vänta på rader över 255. Den
vertikala WAIT-positionen är ju bara en byte, och rymmer således inte högre
tal än 255. Jo, då finns det ett litet knep...Man väntar på den allra sista
positionen som kan inträffa, och då går coppern automatiskt över i ett
"PAL-läge", som man kan kalla det, och $100 adderas till alla WAIT-satsers
vertikala position. Det betyder alltså att position 02 blir position $102
istället.
  Man väntar på "PAL" med följande WAIT-sats:

   DC.W   $FFDF,$FFFE

Jag visar även detta i programexemplet, så titta gärna där också.

Det var allt under rubriken Register för den här gången, men det kommer nya
spännande saker nästa gång!


                              Programexemplet
                              ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Den här gången har jag bara gått in lite mer på copperns programmering, och
programmet visar en gammal effekt - gungande copperbars...
  Att göra dessa balkar är relativt lätt. Först och främst måste man
reservera plats för dem i sin copperlista, och eftersom det är väldigt
tråkigt att skriva 168 waitrader så reserverar vi bara platsen med nollor,
och genererar copperkoden i vårt program.
  Kod-genereringen gör jag i rutinen ClrBars. Den kör jag varje vertikal
blanking, eftersom den samtidigt som den genererar copperkoden, rensar de
gamla balkarna. Tekniken jag använder för att generera koden är väldigt
enkel. Jag pekar på stället där vi ska flytta in koden och sätter sen två
data register till de instruktioner vi behöver. Den ena instruktionen är en
WAIT, och den andra är en MOVE. MOVE-instruktionen ska ju hela tiden vara
$01800000, eftersom vi bara vill sätta bakgrundsfärgen. WAIT-instruktionen
däremot måste vi öka på hela tiden, så att den väntar på raden efter
föregående.
  I rutinen SwingBars sen, skriver jag ut de sex rasterbalkarna en efter
en, med början på den minsta, som alltid ska vara längst bort.
  Jag läser bara av ett sinusvärde från tabellen, och multiplicerar det så
att jag hamnar på rätt plats i copperlistan, och sen för jag in färgvärdena
där. Som sagt, inte så svårt, men kanske lite knepigt för nybörjaren. Kom
gärna med frågor i så fall!
  Om du vill kan du gärna ändra lite i coppergrafiken i slutet på sourcen.
Som du ser är grafiken uppbyggd med vanliga färgbyten, som du kan tex ändra
första balken,

	; Bar 1 (Smalast)
	dc.w	$700
	dc.w	$800
	dc.w	$500
	dc.w	$000

till en gul balk:

	; Bar 1 (Smalast)
	dc.w	$770
	dc.w	$880
	dc.w	$550
	dc.w	$000

  Experimentera på bara! Så kommer du förhoppningsvis förstå hur det
fungerar!
