                           BREV 6
                    MASKINKODSPROGRAMMERING
                          PÅ AMIGAN
Följande lilla program finns inte på programdisketten DISK 1 
skriv in det, assemblera det och starta det genom att skriva "j".
Rör sedan musen fram och tillbaka sidlänges och se på POWER lampan
medan du rör musen.
                    
1  move.w               #$40000,$dff09a
2 
3  mainloop:
4  bset                 #1,$bfe001
5  bsr                  wait1
6  bclr                 #1,$bfe001
7  bsr                  wait2
8
9  btst                 #6,$bfe001
10 bne                  mainloop
11 
12 move.w               #$c000,$dff09a
13 rts
14 wait1:
15
16 move.w               $dff00a,d0
17 and.l                #$ff,d0
18 waitloop1:
19 dbra                 d0,waitloop1
20 rts
21
22 wait2:
23 move.w               $dff00a,d0
24 and.l                #$ff,d0
25 not.b                d0
26 waitloop2:
27 dbra                 d0,waitloop2
28 rts


Här följer en förklaring till vårt lilla program:

Rad 1:  Skruvar av alla INTERRUPT:s

Rad 4:  Sätter BIT 1 i $BFE001 till "1" Detta får POWER lampan 
att slockna

Rad 5:  Hoppar till "WAIT1:".

Rad 6:   Sätter BIT 1 i $BFE001 till "0" Detta får POWER lampan 
att tändas.

Rad 7:  Hoppar till "wait2:"

Rad 9-10:  Kontrollerar att musknappen har tryckts ned.Om inte 
hoppa tillbaka till "mainloop".Har musknappen tryckts ned så 
genomför raderna 12 och 13.

Rad 12:  Skruvar på alla INTERRUPTS igen.

Rad 13:  Hoppar tillbaka till SEKA (avslut).

Rad 16:  Hämtar musposition och lägger den i D0

Rad 17:  Gör en logisk AND med D0 så att vi åter sitter med endast
BIT 0-7 (BIT 8-31 sätts till "0").Nu har vi rensat bort alla BITsen 
så att endast x-positionen för musen ligger kvar.

Rad 18-19:  Denna loop används som en försening.den går i loop så 
många gånger att de tal som ligger i D0 representerar. (muspositionen)

Rad 20:  Hoppar tillbak till programerad 6.

Rad 23:  Lägger in muspositionen i D0.

Rad 24:  Sätter alla BITs med undantag av BIT 0-7 till "0".(Kom 
ihåg att BIT 0-7 förblir orörda)

Rad 25:  Inverterar BIT 0-7 i D0.Det är bara BIT 0-7 som inverteras 
därför att vi använder ".B " i instruktionen (en BYTES är ju 8 BITs).

Rad 26-27:  Går i loop så många gånger som värdet av de tal som ligger
i D0 anger.

Rad 28:  Hoppar tillbak till programrad 9.



Exemplet ovan kommer att fungera så att när du flyttar musen åt 
sidorna,kommer POWER lampan att kunna justeras "steglöst" av och på.
Detta sker med hjälp av lite "joxande och trixande" på följande sätt:

POWER lampan skruvas av och på väldigt fort.

Det ät hela hemligheten! Tänk efter inna du läser vidareom du kan 
komma på varför och hur det fungerar som et gör.

Klarade du det? Troligtvis inte.Det är inte lätt att komma på själv.
Men när du har läst förklaringen nedan så förstår du det-Helt säkert!

Om vi låter lampan vara på likka länge som den är av kommer lampan 
(teoretiskt sätt) att lysa med halv styrka. Om vi låter lampan vara 
släckt 90% av tiden - och tänd 10% av tiden kommer lampan att 
lysa mycket svagt (10% av full styrka).


Denna förskjutning görs med rutinerna "wait1" och "wait2".


                           LOGISK MATEMATIK 

Nu ska vi ta oss an ett område innom programmering som för många ter 
sig svårt att förstå.Det gäller räkneoperationer som utförs med hjälp
av de logiska operationerna: AND,OR och NOT.

Egentligen är det hela väldigt enkelt ock logiskt.Men - som med 
annat här i livet - måste man öva innan man blir duktig.

Längre fram i det här brevet kommer du att stöta på ett uttryck som
ser ut så här:

D=(A AND B) OR ((NOT A) AND C)

Låt oss börja med att förklara hur man löser ett sådant uttryck.

Precis som i vanlig matematik börjar man med att lösa ut de innersta
parenteserna först.Det betyder att i uttrycket (NOT A) skall a 
inverteras. Om A alltså var 1010 så betyder det när (NOT A) är 
utfört 0101.Detta skriver man i logisk matematik med hjälp av ett 
A med ett streck över för att markera invertering (P.ga av att detta
brev är gjort i en ASCII Fil kommer det kanske att se lite underligt
ut men det skall i alla fall   _ vara ett streck över även om det ser 
konstigt ut) så här ser det ut A  

Då kommer det nya uttrycket att se ut så här:
                 _
D=(A AND B) OR ( A  AND C)

I logisk matematik en AND som en multiplikation.Det betyder om vi 
tar oss an parentesen (A AND B),så kan det skrivas som:  A*B I 
vanlig matematik brukar man oftast utelämna multiplikationstecknet.
Det finns där,men det skrivs inte ut. Matematiker ät lata människor!


Nåväl,det gör att uttrycket (A AND B) - som vi kan skriva som A*B
kan förenklas ytterligare till bara AB.

Hela uttrycket kan då,så här långt,skrivas som:
           _    
D=(AB) OR (A AND C)

Vi hoppas att du hänger med så här långt.Låt oss ta oss an den 
sista parentesen.Som tidigare nämts skriver en AND i logiskmatematik
som en multiplikation.Det resulterar i att uttrycket:
 _                      _
(A AND C) kan skrivas: (AC)

Nu har hela uttrycket förenklats ytterligare och kan nu skrivas som:
           _
D=(AB) OR (AC)

Så långt borde allt vara klart som korvspad.Men vi har en logisk 
operation kvar,nämligen en OR.Den skrivs som en addition i logisk 
matematik,alltså med ett plusteckern(+). Det betyder att uttrycket 
nu kan förenklas ännu en gång:
        _
D=(AC)+(AC)

Till sist tas parenteserna bort helt och hållet och uttrycket kommer 
i färdig konverterad form att se ut så här:
     _   
D=AB+AC

Som du säkert vet så är det så i vanlig matematik att multiplikation 
(eller division) utförs före en eventuell addition(eller subtraktion).
Så när man läser det färdiga uttrycket så säger man:

D lika med A gånger B plus A-invers gånger C.

Och med det menar man att:

A och B skall ANDas med varandra
A skall inverteras för att sedan ANDas med c
De två resultaten skall ORas med varandra
Resultatet skall hamna i D

Om du lägger ned mycket arbete på att lära dig det här med maskinkods-
programering att du kan göra det till ett levebröd,så kommer du att 
vara tvungen att konsultera speciallitteratur som behandlar detta 
ämne mer ingående.

OBSERVERA: I logisk matematik används inte räknesätten division 
och subtraktion. I den här kursen behöver du inte mer 
information om logisk matematik än det som vi har förklarat här.


                            BLITTER I 
Ordet blitter är en förkortning för BLOCK IMAGE TRANSFERRER (på 
svenska: block grafik förflyttare).BLITTERn i AMIGAN kan användas 
till många saker. Låt oss börja med att nämna att den bla. kan:

- Kopiera stora mängder med data från ett ställe i minnet till 
ett annat.

- Flytta data BIT-vis i minnet (används bl.a. i SCROLLning).

- Röra figurer på en grafikskärm.

- Flytta runt figurer på skärmen utan att ödelägga eventuell 
grafik som ligger i bakgrunden (under,bakom).

- Rita linjer (sträck) på skärmen.

Alltså,BLITTERn kan hämta data från minnet och tex. göra en logisk 
operation för att sedan lägga tillbaka datan på samma ställe (eller 
någon annanstans) i minnet.

BLITTERn kan använda sig av upp till 4 DMA-kanaler på en gång.Dessa 
DMA-kanaler kallas A,B,C och D.Kanalerna A,B och C kan användas för
att hämta data från minnet,medan kanalen D bara kan användas för att
skriva data till minnet.DMA-kanalerna A,B och C kallas ofta för 
SOURCE-kanaler (översatt: käll-kanaler) för att de bara kan hämta 
data.Kanal D kallas för DESTINATION-kanal på grund av att den bara 
kan skriva till minnet.

Låt oss nu fortsätta med ett litet teoretiskt exempel:

Tänk dig att vi ska kopiera datan som ligger i minnesområdet 
$10000 -$100FF (tillsammans 256 BYTEs) in på adress $20000 -$200FF.


Vi kan då använda operationen D=A (D-kanalen är lika med A-kanalen).
Därefter sätter vi A-kanalen till att peka på adress $10000 och 
D-kanalen på $20000. Längden sätts till $100 och till sist startas 
BLITTERn. Den kommer att arbeta på egen hand så att huvudprocessorn
kan fortsätta med sina uppgifter. Vi kan också - som tidigare nämts
göra logiska operationer med BLITTERn.De tre funktionerna är:
AND,OR och NOT.Dessa kan kombineras på olika sätt.En operation kan 
tex. se ut så här.
     _   
D=AB+AC

Som kan skrivas till:

D=(A AND B) OR ((NOT A) AND C)

Vi kommer att förklara detta närmare vid ett senare tillfälle,när 
vi får användning för det i praktiken. Låt oss nu se på registren 
som BLITTERn använder.

Här följer en tabell över adress pekarna till A,B,C och D:

Namn                    BITs                Adress 
--------------------------------------------------
BLTAPTH (A)             16-31              $DFF050
BLTAPTL (A)              0-15              $DFF052

BLTBPTH (B)             16-31              $DFF04C
BLTBPTL (B)              0-15              $DFF04E

BLTCPTH (C)             16-31              $DFF048
BLTCPTL (C)              0-15              $DFF04A

BLTDPTH (D)             16-31              $DFF054
BLTDPTL (D)              0-15              $DFF056

Modulo-registren för A,B,C och D:

Namn              Adress 
-------------------------
BLTAMOD           $DFF064

BLTBMOD           $DFF062

BLTCMOD           $DFF060

BLTDMOD           $DFF066


BLITTER kontroll-register 0 och dess uppställning:

BLTCON0 - $DFF040


Bit           Funktion 
----------------------
15              ASH3
14              ASH2
13              ASH1
12              ASH0
11              USE A
10              USE B
9		USE C
8		USE D
7		LF7
6		LF6
5		LF5
4		LF4
3		LF3
2		LF2
1		LF1
0		LF0

ASH0 - ASH3     = Rotations-värde för A-kanalen ( A SHIFT).
                  Kan innehålla ett värde från 0 till 15.

USE A - USE D   = Här väljer man vilka DMA-kanaler som skall användas.

LF0 - LF7       = Används för att sätta den logiska operation 
                  som BLITTERn skall använda (LF = LOGIC FUNCTION).


BLITTER kontroll-register 1 och dess uppställning:

Bit           Funktion
---------------------- 
15		BSH3
14		BSH2
13		BSH1
12		BSH0
11		 -
10		 -
9		 -
8		 -
7		 -
6		 -
5		 -
4		EFE
3		IFE
2		FCI
1		DESC
0		LINE


BSH0 - BSH3      = Rotations-värde för B-kanalen (B SHIFT).
                   Kan innehålla ett värde från 0 till 15.

EFE,IFE och FCI  = Används när man fyller figurer.Vi går inte 
närmare in på detta nu,men var lugn - vi kommer tillbaks till det!

DESC = Används för att sätta BLITTERn i "revers" (kallas på data-
språk DESCENDING, och betyder nedåtstigande).Denna metod för att 
BLITa kommer vi tillbaks till i BREV 7.		 

BLITTER storlek (BLITTER SIZE) register och dess uppställning:

BLTSIZE - $DFF058

Bit                  Funktion 
-----------------------------
15			H9
14			H8
13			H7
12			H6
11			H5
10			H4
9			H3
8			H2
7			H1
6			H0
5			W5
4			W4
3			W3
2			W2
1			W1
0			W0

H0 - H9 = Höjden (HEIGHT) på "BLITen", kan innehålla ett värde från 
          0 till 1023.

W0 - W5 = Bredden (WIDTH) på "BLITen", kan innehålla ett värde från
          0 till 63.

Lägg märke till att alla registren som vi har visat här är register 
som du bara kan skriva till (WRITE ONLY).


                           BEGREPPET MODULO 
Vi skall nu fortsätta med att förklara hur MODULO-registren (BLTxMOD)
fungerar.

Studera FIGUR 1 i brevet.Figuren visar ett utsnitt av en grafikskärm.
En ruta i figuren motsvarar 16 PIXELs i bredd och en linje i höjd.
Talen i rutorna är skärmadresserna.Som du säkert ser består en 
linje av 40 BYTEs vilket motsvarar 320 PIXELs bredd. På skärmutsnittet
är en fyrkant uppritad.Denna fyrkant skall fyllas med de data som 
ligger i buffern.Detta kan då göra med en "BLIT".

Som du ser är första adressen (översta vänstra hörnet) i fyrkanten 
126, medan första adressen i buffern är 0.Tänk dig nu att 
skärmminnet ligger på adress $10000 och att buffern ligger på 
adress $20000.Då blir första adressen inne i fyrkanten 
$10000 + 126 = $1007E ($7E = 126) och första adressen i buffern 
$20000 + 0 = $20000.

Den logiska operationen BLITTERn skall utföra är D = A.

Längden på en "BLIT" blir specificerad i höjd och bredd. Höjden 
uppges i antal linjer,medan bredden uppges i block på 16 PIXELs.
Bredden på "BLITen" i detta fall blir 4(4*16 = 64 PIXELs) och 
höjden blir 3 (3 linjer).

Adresserna inne i fyrkanten ligger i radföljd såsom i buffern.Låt 
oss se hur datan skall flyttas för att detta skall bli riktigt:

Buffer     Skärm 
----------------
0     ->   126
2     ->   128
4     ->   130
6     ->   132
8     ->   166
10    ->   168
12    ->   170
14    ->   172
16    ->   206
18    ->   208
20    ->   210
22    ->   212

Som du ser blir det ett "hopp" i radföljden på skärmadress 
132 - 166 och 172 - 206.Detta "hopp" sätts i MODULO-registren.Det 
värde som skall användas för att få rätt "hopplängd",kallar vi för 
en MODULO.

MODULOna i vårt fall blir för A-kanalen,som pekar på buffern,0 
därför att alla data ligger efter varandra,medan MODULOn för 
D-kanalen,som pekar på skärmminnet,uträknas så här: 40 - 8 = 32. 
Detta kan förklaras på följande sätt:

Bredden på "BLITen" är 4 WORDS (eller 4 rutor i figuren).Ett WORD 
innehåller 16 BITs alltså 16 PIXELs.Då blir bredden 64 PIXELs.Vi 
vet också att skärmbredden (linjelängden) är 40 BYTEs.Vi räknar då 
ut det hela så här:

40 - (64/8) = 40 - 8 = 32.

Vi har nu funnit ut följande:

- Startadressen för båda DMA-kanalerna (A=$20000 och D = $1007E)

- MODULOn för båda kanalerna (A = 0 och D = 32).

- Den logiska operationen BLITTERn skall utföra (D = A direkt 
kopiering från A till D).

- Storleken på "BLITen" (höjden = 3 och bredden = 4).

Den fullständiga uppställningen i maskinkod kommer att se ut så här:

1  MOVE.L     #$20000,$DFF050
2  MOVE.L     #$1007E,$DFF054
3  MOVE.W     #$0,$DFF064
4  MOVE.W     #$32,$DFF066
5  MOVE.W     #$09F0,DFF040
6  MOVE.W     #$0000,$DFF042
7  MOVE.L     #$FFFFFFFF,$DFF044
8  MOVE.W     #$00C4,$DFF058

Rad 1: Lägger in värdet #$20000 (adressen till buffern) 
i A-kanal-pekaren.

Rad 2: Lägger in värdet #$1007E (adressen till skärmminnet) i 
D-kanal pekaren.

Rad 3: Sätter MODULO till 0 för A-kanalen.

Rad 4: sätter MODULO till 32 för D-kanalen.

Rad 5: Denna är kanske lite mer invecklad.Se tabellen för registret
       (BLTCON0).Där ser du att detta register sätter bl.a.den logiska
       funktion som BLITTERn skall utföra.Dessutom anges det vilka DMA-
       kanaler som skall användas(i det här fallet A och D).När det 
       gäller den logiska operationen,så har vi gjort en tabell över 
       de mest  använda operationerna bak i brevet.Värdet för 
       operationen A = D som används i detta fall är $F0.

Rad 6: Detta register sätts i regel till 0.Vi kommer tillbaks till 
       detta register senare när vi får användning för det.Se även
       tabellen över registret (BLTCON1).

Rad 7: Detta register sätts till $FFFFFFFF.Vi kommer inte att 
       förklara vad detta register gör just nu,men om du vill 
       exprimentera med BLITning själv,kan du lugnt sätta detta 
        register till $FFFFFFFF hela tiden (för den som är nyfiken 
        heter detta register BLITTER A MASK).

Rad 8: Här kommer det register som bestämmer hur sror BLITen skall 
       vara (höjd och bredd).Detta kan räknas ut med en enkel formel:

       (höjd * 64) + bredd

Alltså:   3 (linjer) * 64 + 4 (WORDs , som motsvarar 64 PIXELs) =
          196 (DECIMALT) = $00C4 (HEXADECIMALT).


Låt oss nu se på ett exempel.Exemplet finns även på DISK 1 
där det heter MC0601.

1  move.w	#$4000,$dff09a
2 
3  or.b	#%10000000,$bfd100
4  and.b	#%10000111,$bfd100
5 
6  move.w	#$01a0,$dff096
7
8  move.w	#$1200,$dff100
9 move.w	#$0000,$dff102
10 move.w	#$0000,$dff104
11 move.w	#0,$dff108
12 move.w	#0,$dff10a
13 move.w	#$2c81,$dff08e
14 move.w	#$f4c1,$dff090
15 move.w	#$38c1,$dff090
16 move.w	#$0038,$dff092
17 move.w	#$00d0,$dff094
18 
19 lea.l	screen,a1
20 lea.l	bplcop,a2
21 move.l	a1,d1
22 move.w	d1,6(a2)
23 swap	d1
24 move.w	d1,2(a2)
25 
26 lea.l	copper,a1
27 move.l	a1,$dff080
28 move.w	#$8180,$dff096
29 
30 mainloop:
31 move.l	$dff004,d0
32 asr.l	#8,d0
33 andi.l	#$1ff,d0
34 cmp.w	#300,d0
35 bne	mainloop
36 
37 bsr	clear
38 
39 bsr	blitin
40 
41 btst	#6,$bfe001
42 bne	mainloop
43 
44 move.w	#$0080,$dff096
45 
46 move.l	$4,a6
47 move.l	156(a6),a6
48 move.l	38(a6),$dff080
49 
50 move.w	#$80a0,$dff096
51 
52 move.w	#$c000,$dff09a
53 rts
54 
55 clear:
56 lea.l	screen,a1
57 
58 waitblit1:
59 btst	#6,$dff002
60 bne	waitblit1
61 
62 move.l	a1,$dff054
63 move.w	#0,$dff066
64 move.w	#$0100,$dff040
65 move.w	#$0000,$dff042
66 move.w	#$4014,$dff058
67 rts
68 
69 pos:
70 dc.l	0
71 
72 blitin:
73 lea.l	pos,a1
74 move.l	(a1),d1
75 addq.l	#1,(a1)
76
77 cmp.w	#216,d1
78 bne	notbottom
79 
80 clr.l	d1
81 clr.l	(a1)
82 
83 notbottom:
84 lea.l	screen,a1
85 mulu	#40,d1
86 add.l	d1,a1
87 add.l	#12,a1
88 
89 lea.l	object,a2
90
91 waitblit2:
92 btst	#6,$dff002
93 bne	waitblit2
94 
95 move.l	a1,$dff054
96 move.l	a2,$dff050
97 move.w	#24,$dff066
98 move.w	#0,$dff064
99 move.l	#$ffffffff,$dff044
100 move.w	#$09f0,$dff040
101 move.w	#$0000,$dff042
102 move.w	#$0a08,$dff058
103 rts
104 
105 copper:
106 dc.w	$2c01,$fffe
107 dc.w	$0100,$1200
108 
109 bplcop:
110 dc.w	$00e0,$0000
111 dc.w	$00e2,$0000
112 
113 dc.w	$0180,$0000
114 dc.w	$0182,$00ff
115 
116 dc.w	$ffdf,$fffe
117 
118 dc.w	$2c01,$fffe
119 dc.w	$0100,$0200
120 dc.w	$ffff,$fffe
121 
122 screen:
123 blk.l	2560,0
124 
125 object:
126 blk.l	160,0


Vi börjar med att sätta upp en enkel förklaring till programmet:

Rad 1 - 28:  Skruvar av INTERRUPTerna och diskettstationen.Sätter 
             upp en skärm med ett BITPLANE på 320 * 256 PIXELs i 
             LORES och startar COPPERn.

Rad 30 - 42: Detta är huvudprogrammet (huvudLOOPen).

Rad 44 - 53: Hämtar tillbaka den gamla skärmen och avslutar programmet

Rad 55 - 67: Detta är en underrutin (SUBRUTINE) som rensar skärmen
             (lägger 0 i alla skärmadresser).Detta sker med BLITTERn.

Rad 72- 103: Denna under-rutin "BLITTRAR" in figuren på skärmen. 
             Detta sker också med BLITTERn.

Rad 105-120: här finns vår COPER lista.

Rad 122-126: Det första "BLK"-kommandot lägger av 10240 BYTEs 
             till skärmminnet.Det andra lägger av 640 BYTEs till 
              figurdatan (som också finns på DISK 1).

Låt oss nu förklara mer ingående de okända delarna av programmet:

Rad 1 - 28: Detta borde alla känna till nu.

Rad 31 -35: Denna rutin vänta till elektronstrålen har nått 
            skärmlinje 300.

Rad 37:     Här sker hopp till rutinen "clear".

Rad 39:     Här sker hopp till rutinen "blitin".

Rad 41-42:  Kontrollerar om vänster musknapp har tryckts på.Om 
            inte hoppa tillbaka till "mainloop"

Rad 44-53:  Här avslutas programmet detta borde vara välkänt.

Rad 55:     Denna rutin rensar skärmen. (lägger värdet 0 i alla 
            skärmadresser).Vi använder i denna BLITen bara D-kanalen
            (alltså inga SOURCE kanaler).Detta får till resultat att
            det bara läggs ut nollor i minnet.

Rad 56:     Lägg in adressen till skärmminnet (screen) i A1.

Rad 58-60:  Denna rutin väntar med att gå vidare tills BLITTERn 
            är klar med sin tidigare uppgift (eller BLIT).

Rad 62:     Lägg in adressen till skärmminnet i D-kanal pekaren.

Rad 63:     Sätt MODULO för D-kanalen till 0.

Rad 64:     Välj enbart D-kanalen och ingen logisk operation.

Rad 65:     Lägg in värdet 0 i BLTCON1.

Rad 66:     Ange storlek på BLITen.Höjden sätter vi till 256 och
            bredden till 20 WORDs (20 * 16 = 320).När du skriver till
            detta register startar BLITTERn (DMA-kanalerna) av sig
            själv.Därför måste du sätta storleken på BLITen ($DFF058)
            sist.Alltså: Det är inte nödvändigt att sätta några BITs i
            DMACON-registret ($DFF096) för att BLITTERn skall starta.

Rad 67:     Hoppa tillbaks till huvudrutinen.

Rad 69-70:  Här har vi deklarerat ett LONGWORD för att hålla positionen
            till figuren på skärmen.

Rad 72:     Denna rutin BLITar in figuren på skärmen.

Rad 73:     Hämta in adressen till "pos" i A1.

Rad 74:     Lägg in innehållet från adressen som A1 pekar på i D1.

Rad 75:     Lägg till 1 till det värde som adressen i A1 pekar på.
            Detta lägger till 1 i vårt deklarerade LONGWORD och inte
            i register D1.

Rad 77:     Jämför D1 med 216.

Rad 78:     Om D1 är olikt 216,hoppa till "notbuttom".Alltså:
            kontrollera om figuren har kommit till båtten på skärmen.

Rad 80:     Sätt alla BITsen i D1 till 0.

Rad 81:     Sätt alla BITsen som adressen i A1 pekar på till 0.

Rad 84:     Lägg in adressen till "screen" i A1.

Rad 85:     Multiplicera D1 med 40.Detta görs för att en skärmlinje 
            innehåller 40 BYTEs.Denna instruktion har vi inte haft
            tidigare,men vi tror den förklarar sig själv.I ett senare
            brev kommer vi att ta upp denna instruktion i samband med
            s.k. signerade värden.För den nyfikne har MC-68000 också
            en instruktion som kan utföra en division.Denna kan t.ex.
            se ut så här: DIVU #5,D1.

Rad 86:     Addera värdet som ligger i D1 till värdet i A1.

Rad 87:     Addera 12 till värdet i A1.Detta gör att figuren centreras
            horisontellt på skärmen.

Rad 89:     Lägg in adressen till figuren i A2.

Rad 91-93:  Vänta med att gå vidare tills eventuellt annat BLITTER-
            arbete är färdigt.

Rad 95:     Lägg in värdet (skärmadressen) som ligger i A1 i pekaren
            för D-kanalen.

Rad 96:     Lägg in värdet (figuradressen) som ligger i A2 i pekaren
            för A-kanalen.

Rad 97:     Sätt MODULON till D-kanalen till 24.

Rad 98:     Sätt MODULOn till A-kanalen till 0.

Rad 99:     Sätt A MASK till $FFFFFFFF.Användningen av detta register
            kommer vi inte att förklara nu (men vi kommer tillbaks  
            till det!).

Rad 100:    Ange användningen av A och D och sätt den logiska opera-
            tionen till: D = A.

Rad 101:    Lägg in värdet 0 i BLTCON1 ($DFF042).

Rad 102:    Sätt storleken på BLITen.Höjd = 40 (linjer) och bredd = 8
            WORDs (8 * 16 = 128 PIXELs).

Rad 103:    Hoppa tillbaks till huvudrutinen.

Rad 105-120:Här är vår COPPER-lista deklarerad.

Rad 122-126:Här är vår skärmbuffer och figurbuffer deklarerad.


För att köra det här programmet måste du först assemblera det sedan 
hämta in (med kommandot "ri") filen "OBJECT" som ligger i samma 
katalog (DIRECTORY)  som själva käll-koden (SOURCE CODE) gör.

Kom ihåg att BLITTERn bara kan arbeta i CHIP-RAM på samma linje 
med COPPER,SPRITE, etc.


                          BLITTER II 
I detta kapitel kommer vi att förklara hur BLITTERn kan flytta en 
figur på skärmen utan att beröra (eller förstöra) grafikdatan som 
redan ligger på skärmen.

Studera figur 2 (finns på Brev6.Bild1) Objectet är figuren som skall
BLITas in på skärmen.MASKen är en figur som täcker över objectet.
Alltså: Den har samma form och storlek som objectet,men endast 
ett BITPLANE.

Låt oss nu förklara hur det hela fungerar:

- Först läses musens position.

- Därefter kopieras den del (bestämmt av muspositionen) av 
skärmminnet som figuren skall läggas in i,över till bakgrunds 
buffern.

- Nu BLITas figuren in.Om vi kopierar minnet direkt från 
objektbuffern in i skärmminnet (BITMAPen),skulle vi få en svart ram 
runt den runda figuren.Detta undgår vi på följande sätt:
                                                   _     
Den logiska operationen för denna BLITen är D = AB+AC

Detta kan skrivas på ett annat sätt:

D = (mask * objekt) + ( mask  * bakgrund)

Ett streck under MASK betyder att BITsen som läses in i BLITTERn 
från MASKbuffern inverteras.Det vill säga att en nolla (0) blir 
ett (1) och ett (1) blir noll (0).

Om vi tänker BIT-vis så kommer denna operation att resultera i 
följande:

Där MASKen innehåller nollor (utanför rundningen) kommer datan som 
ligger i bakgrundsbuffern att kopieras (BLITas) in på skärmen och 
där MASKen innehåller ettor (inne i rundningen) kommer datan som 
ligger i objektbuffern (figuren) att kopieras in på skärmen.

- Till sist kopieras bakgrunden in på skärmen så att den blir som 
den var från början.

Hela denna rutin sker konternuerligt så att det kommer att se 
"flytande" ut när figuren flyttas runt på skärmen.

Vi skall nu fortsätta med en enkel förklaring av programmexempel 
MC0602 (detta exempel finns bara på DISK 1):

Rad 1 - 17:     Sätter upp en skärm med upplösningen 320 * 256 
                PIXELs och med 5 BITPLANEs (32 färger).

Rad 19 -25:     Här läggs färgerna som ligger i början av skärmbuffern 
                in i färgregistren.

Rad 27 -40:     Här läggs adresserna till de 5 BITPLANen in i copper
                listan.

Rad 42 -44:     Lägg adressen till COPPER-listan i COPPER-pekaren.

Rad 46:         Starta BITPLANE- och COPPER-DMAna.Som du säkert ser
                har vi satt en extra bit i detta register.Detta är 
                BIT 10 i DMACON-registret.Om man sätter denna BIT 
                kommer BLITTERn i vissa fall att bli något snabbare.
                Varför detta sker skall vi förklara i ett senare brev.

Rad 48 -49:     Musen läses av och bakgrunden lagras undan som en 
                förstagångsoperation.

Rad 52- 65:     Detta är huvudrutinen som borde vara lätt att förstå.

Rad 67- 77:     Hämtar tillbaka den gamla COPPER-listan och avslutar
                programmet.

Rad 79-121:     Denna rutin BLITar in figuren.

Rad 123-171:    Denna rutin roterar figuren och MASKen (BIT-vis) så
                att figuren kan flyttas PIXEL-vis även i horison-
                talled.

Rad 173-185:    Detta är rutinen som läser av muspositionen.

Rad 187-222:    Denna rutin kopierar bakgrunden från skärmen
                (skärmminnet) in i bakgrundsbuffern ("backbuffer").

Rad 224-259:    Denna rutin kopierar bakgunden från bakgrundsbuffern
                och in på skärmen.

Rad 261-280:    Här är vår COPPER-lista deklarerad.

Rad 282-298:    Här är alla de nödvändiga buffrarna deklarerade.

Rad 300-303:    Här har vi deklarerat två LONGWORDs till att hålla
                ordning på muspositionerna (X- och Y-koordinaterna).



Vi skall nu förklara alla underrutiner (SUBRUTINER) lite närmare:

Rad 80:       Lägg in adressen till "maskbuffer" i A1.

Rad 81:       Lägg in adressen till "backbuffer" i A3.

Rad 82:       Lägg in adressen till "figbuffer" i A2.

Rad 83:       Lägg in adressen till skärmminnet ("screen") i A4.

Rad 84:       Lägg 64 till värdet i A4.Detta görs för att hoppa över
              färgdatan som ligger i början av skärmbuffern.

Rad 86:       Hämta adressen till "mousex" och lägg den i A0.

Rad 87:       Lägg in det värde som finns på den adress som A0 pekar
              på i D0.

Rad 88-89:    Utför detsamma för y-positionen till musen.

Rad 91:       Flytta innehållet i D0 4 BITs till höger.Denna 
              instruktion utför egentligen en division med 16
              (2 * 2 * 2 * 2)

Rad 92:       Flytta innehållet i D0 en (1) BIT till vänster.Denna
              instruktion utför egentligen en multiplikation med 2

Rad 93:       Multiplicerar D1 med 40.Detta gör att y-positionen 
              blir riktig i förhållande till skärmen (1 linje på 
              skärmen är ju 40 BYTEs).

Rad 94:       Addera innehållet i D0 till värdet i A4.

Rad 95:       Addera innehållet i D1 till värdet i A4

Rad 97:       Lägger in värdet 4 i D7.

Rad 99-101:   Vänta tills BLITTERn är ledig.

Rad 103:      Lägg in värdet som ligger i A4 i D-Pekaren

Rad 104:      Lägg in värdet som ligger i A1 i A-Pekaren

Rad 105:      Lägg in värdet som ligger i A2 i B-Pekaren

Rad 106:      Lägg in värdet som ligger i A3 i C-Pekaren.

Rad 107:      Sätt MODULOn till D-kanalen tilll 32 (figuren är 64
              PIXELs bred, vilket ger resultatet: 40 - (64/8)=32.

Rad 108-110:  Sätt MODULOn till A,B och C-kanalen till 0.

Rad 111:      Lägg in värdet $FFFFFFFF i A MASK-registret.
                                             _
Rad 112:      Här sätts operationen D = AB + AC och alla kanaler
              väljs.

Rad 113:      Lägg in värdet 0 i BLTCON1.

Rad 114:      Här sätts storleken på BLITen. Höjden = 45 (linjer
              PIXELs) och bredden = 4 WORDs (64 Pixels)

Rad 116:      Lägg till 360 i A2 så att A2 pekar på nästa bitplane
              i figuren (45*(64/8)=360).

Rad 117:      Lägg till 360 i A3 (bakgrund).

Rad 118:      Lägg till 10240 i A4 (skärm). MASK-buffern blir
              densamma därför att den bara innehåller ett BITPLANE.

Rad 120:      Upprepa denna BLIT 5 gånger (för alla 5 bitplanes)

Rad 121:      Hoppa tillbaks till huvudrutinen.

Rad 124:      Lägg in adressen till "fig" i A1

Rad 125:      Lägg in adressen till "figbuffer" i A2

Rad 127-128:  Hämta in x-positionen till musen i D1.

Rad 130:      Sätt alla BITsen med undantag av BIT 0-3 i D1 till 0.

Rad 131-132:  Innehållet i D1 flyttas tillsammans 12 BITs till
              vänster. Man måste flytta två gånger därför att
              MC-68000 inte tillåter fler än 8 flyttningar åt gången
              med denna metod.

Rad 133:      Lägg till värdet $09f0 i D1. D1 innehåller nu $x9f0,
              där "x" är hur många BITs datan skall flyttas i 
              BLITTERn. Vi går inte in på hur BLITTERn utför sådana
              flyttningar förrän i BREV 7. Det den här BLITen utför
              är att hämta datan från "fig", flytta dem "x"
              gånger till höger och lägga resultatet i "figbuffer".
              Den logiska operationen för denna BLIT är D=A och D
              och A kanalen är vald.

Rad 135:      Lägg in värdet 4 i D7 (används som räknare).

Rad 137-139:  Vänta tills BLITTERn är ledig.

Rad 141:      Lägg in värdet som ligger i A2 i D-pekaren.

Rad 142:      Lägg in värdet som ligger i A1 i A-pekaren.

Rad 143-144:  Sätt MODULOn till A och D-kanalen till 0.

Rad 145:      Sätt A MASK-registret till $FFFFFFFF

Rad 146:      Lägg in värdet som ligger i D1 i BLTCON0

Rad 147:      Lägg in värdet 0 i BLTCON1.

Rad 148:      Storleken på denna BLIT är också 45 linjer * 4 WORDs
              (8 BYTEs eller 65 PIXELs).

Rad 150-151:  Lägg till 360 i både A1 och A2 så att det pekas på
              nästa BITPLANE.

Rad 153:      Detta upprepas för alla 5 BITPLANEs.

Rad 155-169:  Detta sker på samma särr även för MASKen. Den enda
              skillnaden är att MASKen bara har ett BITPLANE.

Rad 171:      Hoppa tillbaks till huvudrutinen.

Rad 174-185:  Denna rutin läser av musens position och lägger
              värdena i de två deklarerade "mousex" och "mousey".
              Vi förklarar inte det här registret nu ($dff00a).
              Vi kommer tillbaks till musrutinen i BREV 11.

Rad 188:      Lägg in adressen till "screen" i A1.

Rad 189:      Lägg in 64 till värdet i A1. Detta gör att A1 hoppar
              över färgdatan som ligger i början av skärmbuffern,

Rad 190:      Lägg in adressen till "backbuffer" i A2.

Rad 192-195:  Hämta muspositionerna (x- och y-koordinaterna) och
              lägg dem i respektive D0 och D1.

Rad 197-201:  Hitta första BLIT-positinen på skärmen.

Rad 203:      lägg in värdet 4 i D7.

Rad 205-207:  Vänta tills BLITTERn är ledig.

Rad 209:      Lägg in värdet i A2 i D-pekaren.

Rad 210:      Lägg in värdet i A1 i A-pekaren.

Rad 211:      Sätt MODULOn till A-kanalen till 0.

Rad 212:      MODULOn till A-kanalen sätts till 32.

Rad 213:      A MASK-registret sätts till $FFFFFFFF

Rad 214:      Sätt den logiska operationen D=a och välj A- och D-
              kanalen som skall användas.

Rad 215:      Lägg in värdet 0 i BLTCON1.

Rad 216:      Sätt storleken till 45 linjer * 4 WORDs.

Rad 218-219:  Addera 10240 till värdet i A1 och addera 360 till
              värdet i A2.

Rad 221:      Denna BLIT upprepas 5 gånger

Rad 222:      Hoppa tillbaks till huvudrutinen.

Rad 224-259:  Denna rutin är nästan precis likadan som "storeback"
              rutinen. Skillnaden är att datan BLITas i motsatt
              riktning (från bakgrundsbuffern till skärmminnet).

För att köra detta programm måste du assemblera det först, sedan
måste du läsa in filerna SCREEN,FIG och MASK (med kommandot
"ri"). De ligger i samma DIRECTORY som SOURCE-filen.

                     LÖSNINGAR TILL BREV 5

Uppgift 0501:   Positinen x blir 363, positinen y blir 238
                och höjden blir 35. Alla tal är angivna
                DECIMALT.

Uppgift 0502:   En SPRITE kan vara 16 PIXELs bred.

Uppgift 0503:   I AMIGA finns det 8 sprites.

Uppgift 0504:   D0 kommer att se ut så här:
                01100101101001101011011100010010

Uppgift 0505:   Adressen som D0 får sitt värde ifrån blir
                $000554.

Uppgift 0506:   STACKen i AMIGA används b.la till att:

                Mellan lagra data.

                Lagara returnerings adresser (för BSR och RTS) till
                proccessorn.

Uppgift 0601:   Försök att översätta MODULO till et bra 
                svenskt ord.

Uppgift 0602:   Hur hög och hur bred blir denna BLIT som
                har denna BLTSIZE:$1A69
                                               _         
Uppgift 0603:   Vad händer med A i detta Fall: A

Uppgift 0604:   Hur många PIXELs horisontellt är det minsta
                som kan definieras i BLTSIZE (med undantag 
                av 0)?


        TABELL ÖVER BLITTERNS MEST ANVÄNDA LOGISKA FUNKTIONER


LF      Värde                   LF      Värde
-------------                   -------------
D=A     $F0                        D=AB
  _                                   _
D=A     $0F                        D=AB
                                     _
D=B     $CC                        D=AB
  _                                  __
D=B     $33                        D=AB
                
D=C     $AA                        D=BC
  _                                   _                          
D=C     $55                        D=BC
                                     _
D=AC    $A0                        D=BC
   _                                 __
D=AC    $50                        D=BC
  _                                    _
D=AC    $0A                        D=A+B  
  __                                 _ _  
D=AC    $05                        D=A+B
                                       _
D=A+B   $FC                        D=A+C
  _                                  _ _   
D=A+B   $CF                        D=A+C
                                       _ 
D=A+C   $FA                        D=B+C
  _                                  _ _  
D=A+C   $AF                        D=B+C
                                        _
D=B+C   $EE                        D=AB+AC
  _                                  _
D=B+C   $BB                        D=AB+AC
