home *** CD-ROM | disk | FTP | other *** search
- A S S E M B L E R - K U R S (c) Jeff Kandle 1990
-
- 28.Teil...
-
- Wie ich versprochen habe, kommen wir jetzt an etwas schwierigere
- Blitterthemen.
- Also ran an die logischen Verknuepfungen.
-
- Wer von euch ein bisschen mit dem letzten Bob-Listing gearbeitet hat, der
- hat bestimmt einige unangenehme eigenschaften des Programm`s kennengelernt.
- Zum Beispiel das wenn mehrere Bob`s sich ueberschneiden, immer nur der
- oberste ganz dargestellt wird, und von den anderen immer mehr oder weniger
- fehlt.
-
- Die Erklaerung ist einfach. Wir Kopieren ja bloss von A nach D. Alles was
- ich A steht geht auch nach D.
- Das ist keine Verknupfung. Schalten wir mal eben auf eine Plane, da kann
- man die Funktion besser erkennen.
-
- Es soll ja am Ende so Funktionieren das in der Bitplane alles gesetzt wird
- was auch im Bob gesetzt ist. Sobald aber mal das aktuelle Bit im Bob nicht
- gesetzt ist, soll das gesetzt werden was dort vorher stand.
- Da wir aber nicht Logisch mit D arbeiten koennen, sondern in D immer nur
- das Ergebnis steht, muessen wir eine weitere Quelle dazu schalten.
- Dazu nehmen wir die Quelle B.
-
- Der Blitteraufruf sieht dann so aus das A auf den einplaneBob zeigt, B auf
- den bereich zeigt der von dem Bob ueberschrieben wird, und D auf den
- gleichen Bereich, allerdings als Ziel....
-
- Im BLTCON0-Register muss man dann nur noch die Verknuepfung
-
- D = A or B
-
- Das heisst auf Deutsch - D ist immer dann 1, wenn A oder B 1 ist. Wichtig
- ist dabei das Oder.
-
- Manche werden sich jetzt fragen ob ich noch ganz echt bin. Aber trotzdem
- werde ich jetzt wieder mal die Bobs kurz verlassen, da ich ja immer zu dem
- jeweiligen Stand des Koennens in Assembler ein paar andere Sachen mache.
- Das finde ich naemlich sehr viel besser.
-
- Kommen wir nun zu einer Sache die vor einem Jahr das Markenzeichen fuer
- gute Intro/Demo-Programmierer war. Mittlerweile ist es allerdings Standart
- geworden. Das ist zwar etwas traurig aber es ist nach wie vor eine tolle
- Sache, an der man seine Programmtechnischen Faehigkeiten sehr gut messen
- kann.
-
- 22.Realisierung eines einfachen Sinusscrollers mit dem Blitter
-
- Als Grundprogramm nehmen wir einfach das Laufschriftprogramm was wir im
- Kapitel Laufschrift geschrieben haben.
- Es muss auch nicht soviel daran geaendert werden, deshalb bietet es sich
- an.
-
- Schauen wir uns mal an was der Prozessor dem Blitter zu tun gibt.
- Der Prozessor laesst den Blitter jede 1/50 Sekunde den Laufschrift Bereich
- um eins nach Links schieben. Gleichzeitig zaehlt er jedoch ob der Aktuelle
- Buchstabe schon aus dem Puffer herausgeschoben ist. Sobald das passiert ist
- laesst er den Blitter einen neue Buchstaben in den Puffer kopieren.
-
- Diese Kopierroutine ist einfach Mathematisch darzustellen.
-
- D = A
-
- Also...Ist A = 1 dann ist auch D = 1, ist A = 0 dann....
- Somit wird auch der Muell der beim Linksrotieren des Puffer hinten
- reingeschoben wird, ueberschrieben. Schoen und gut.
-
- Jetzt wollen wir uns mal ueberlegen wie man die Wellen, oder einfacher,
- ueberhaupt einen Vertikalen versatz hinkriegen koennen.
- Wenn wir immer mit einem Wort arbeiten, ist das ja nicht schwer. Das
- naechste Ziel des Blitters liegt dann eben 3 oder 4 zeilen unter dem
- vorherigen. Was ist aber wenn wir die abstufungen Steiler machen wollen ?
-
- Wir muessten dann mehrmals pro Wort um eine Zeile runtergehen. Sagen wir
- mal immer 4 Bits, und dann eine Zeile runter.
- Aber wie kriegt man nur 4 Bits kopiert, und wie weiss der Blitter welche 4
- Bits ich will ?
-
- Dazu gibt es Bltafwm und Bltalwm, die beiden Masken die man ueber das erste
- und letzte Word der zu kopierenden Zeilen legen kann. Damit markieren wir
- einfach die Bits die wir kopieren wollen. Nachdem das passiert ist schieben
- wir die Maske auf die naechsten 4 Bits, und starten die Aktion fuer das
- Wort nochmal. Solange bis das Wort kopiert ist. Ihr koennt euch sicherlich
- vorstellen was das fuer eine arbeit fuer den Blitter ist. Wiegesagt -
- erstes und letztes Wort der Zeile. Falls die Zeile nur ein Wort, wie in
- unserem Fall, breit ist, dann werden die Masken uebereinander gelegt. Um
- dann sinnvolle angaben zu erhalten, muessen die beiden Masken jeweils
- denselben Inhalt haben. Wenn ich also aus dem Wort nur Bit 1,2,3 und 4
- kopieren will, dann muessen die Masken fuer die Register ungefaehr so !
- aussehen.
-
- BltaFwm = %1111000000000000
- BltaLwm = %1111000000000000
-
- So, und was geschieht mit dem Rest ? Der Blitter schreibt an ihre Stelle im
- Ziel, egal was in der Quelle steht, immer eine Null. Somit haetten wir dann
- nur die 4 Bits die wir gewuenscht haben, kopiert.
-
- Was passiert aber wenn ich die ersten 4 Bits kopiert habe, die Maske
- verschoben habe, und nun die Bits 5 - 8 um eine zeile verschoben, Kopieren
- will. Da Nullen ja auch Kopiert werden, und die ausmaskierten Bits, als 0
- Interpretiert werden, wird der groesste Teil der ersten 4 Bits geloescht.
-
- Das ist dann ehrlichgesagt - Scheisse !, und ganz bestimmt nicht das was
- wir wollen.
- Deshalb muessen wir es so einrichten, das der Blitter die gesetzten Bits im
- Ziel, die durch nullen ueberschrieben werden wuerden, zu beruecksichtigen.
-
- Die Logische verknuepfung die wir dafuer einstellen muessen, ist
-
- D = A ^ B
-
- Was auf Deutsch heisst. D ist auf jedenfall 1 wenn A oder B 1 ist. Wenn
- beide 1 sind, was aber in unserem Fall nicht vorkommen wird, ist es
- natuerlich auch 1.
-
- Auf diese Art und Weise, werden die davor kopierten Bitspalten, in Ruhe
- gelassen, und halten ihr aussehen.
-
- Ich will das ebenbesprochene mal Source-Code-Maessig unterstuetzen.
- Es kopiert einen im Source enthaltenen Bob, jeweils um eine Zeile versatz
- pro Bit auf den Screen.
-
-
- Start:
- Execbase= 4
- Openlibrary= -408
- Vhposr= $dff006
- Forbid= -30-102
- Permit= -30-108
- Bltafwm= $dff044
- Bltalwm= $dff046
- Bltcon0= $dff040
- Bltcon1= $dff042
- Bltamod= $dff064
- Bltbmod= $dff062
- Bltdmod= $dff066
- Bltapt= $dff050
- Bltbpt= $dff04c
- Bltdpt= $dff054
- Dmacon= $dff096
- Intena= $dff09a
- Dmaconr= $dff002
- Bltsize= $dff058
-
-
- Move.w #$0020,Dmacon
- Move.w #$4000,Intena
- Move.l Execbase.w,a6
- Jsr Forbid(a6)
-
-
- Move.l #$60000,a0
- Move.l #$9588/4,d0
- Clearloop:
- Move.l #$0,(a0)+
- Dbf d0,Clearloop
-
-
- Bsr.l Makecl
- Bsr.l Bobmaker ; Aufruf der Bobroutine
-
- Wait:
- Btst #6,$bfe001
- Bne Wait
-
- Move.l Execbase.w,a6
- Jsr Permit(a6)
- Lea Gfxname(pc),a1
- Jsr Openlibrary(a6)
- Move.l d0,a6
- Move.w #$83e0,Dmacon
- Move.w #$c000,Intena
- Move.l 38(a6),$dff080
- Moveq #0,d0
- Rts
- Makecl:
- Lea $05f000,a0
- Move.l a0,$dff080
-
- Move.l #$00e00006,(a0)+
- Move.l #$00e20000,(a0)+
- Move.l #$008e1a64,(a0)+
- Move.l #$009039d1,(a0)+
- Move.l #$00920030,(a0)+
- Move.l #$009400d8,(a0)+
- Move.l #$01001200,(a0)+
- ;----------------------------------------------
- Move.l #$01800000,(a0)+
- Move.l #$01820fff,(a0)+
- ;----------------------------------------------
- Move.l #$fffffffe,(a0)+
- Rts
- Waitblit:
- Btst #6,Dmaconr ; Wartet bis Blitter fertig
- Bne.s Waitblit
- Rts
- Bobmaker:
- Move.w #$0f,d7 ; Counter fuer die Spalten-
- ; Anzahl
- Move.w #%1000000000000000,d0 ; Erste Maske
- Move.l #$61088,d1 ; Erste Adressen
- Loop: Bsr.l Set_bob ; Bob setzen
- Add.l #$2c,d1 ; Eine Zeile runter
- Ror.l #1,d0 ; Maske 1 Bit verschieben
- Dbf d7,Loop ; Schleife ob schon ganzer
- ; Bob ?
- Rts
-
-
- Set_bob:
- Bsr.s Waitblit
- Move.w d0,Bltafwm
- Move.w d0,Bltalwm
- Move.w #%0000110100111100,Bltcon0
- Move.w #0,Bltamod ; Quellmodulo = 0 (rawblit)
- Move.w #42,Bltdmod ; Zielmodulo = 42 (planes = $2c)
- Move.w #42,Bltbmod
- Move.l #Bob,Bltapt ; Quelladr.
- Move.l d1,Bltbpt
- Move.l d1,Bltdpt ; Zieladr.
- Move.w #16*64+1,Bltsize ; Bltsize und Start
- Rts
-
- Gfxname: dc.b "graphics.library",0
-
- even
-
- Bob:
- Dc.w %1111111111111111
- Dc.w %0000000000110000
- Dc.w %0000000001100000
- Dc.w %0000000011000000
- Dc.w %0000000110000000
- Dc.w %0000001100000000
- Dc.w %0000111111000000
- Dc.w %0001111111100000
- Dc.w %0001111111100000
- Dc.w %0010000000000000
- Dc.w %0001000000000000
- Dc.w %0000100011110000
- Dc.w %0000010000000000
- Dc.w %0000001000000000
- Dc.w %0000000100000000
- Dc.w %1111111111111111
-
-
- Das Listing ist ja ein Bisschen Dokumentiert. Ihr duerftet aber keine
- Probleme mehr damit haben.
- Mir hat ein bekannter gesagt, das es eine Sache gibt die ihn an diesem Kurs
- stoert. Das ich viel zu viel zeige, und die Leute nicht selber denken
- lasse.
- Ich habe aber sonst keine Klagen gehoert, deshalb schaetze ich mal das euch
- der Kurs ganz gut gefaellt. Naja, aber trotzdem, ich werde jetzt in den
- letzten Teile die Kritik hinnehmen und befolgen.
-
- Um daraus jetzt eine Sinusschrift zu machen muesst ihr folgendes machen.
-
- Diese Kopierroutine in das Laufschrift Programm einsetzen. Auf eine ganze
- Zeile erweitern, und die Zeilen in die Kopiert wird aus einer Tabelle lesen
- lassen. Die alte Laufschrift muesst ihr dann in einen Puffer ablaufen
- lassen, sodas erst diese Kopierroutine die Schrift auf den Screen bringt.
-
- Mehr nicht...
-
- Eigentlich war es das zu der Sinuslaufschrift..Wenn ihr das Prinzip
- geschnallt habt, dann ist ja alles O.K...Verschiedene Variationen werdet
- ihr ja sicher selber machen. Nur halt soviel. Ueberlegt euch immer vorher
- ob es in einem Demo immer eine Sinusschrift sein muss. Denn diese ganzen
- Blitteraktionen nehmen auf dem Prozessor viel Zeit weg, und deshalb kann
- fuer das restliche Intro nicht mehr soviel Zeit aufgebracht werden. Wenn
- ihr das mal durchrechnet was der Blitter da schon an Zeit braucht, dann
- wisst ihr warum die eigentlich garnicht so schwierigen Sinusscroller nicht
- so oft eingesetzt werden.
- Es gibt ja genug andere schoene Effekte die sich fuer Intro`s eignen. Und
- nicht der, der am besten andere Ideen nachprogrammiert macht von sich
- reden, sondern der, der die schoensten eigenen Ideen hat. Wobei Egal ist
- wie einfach sie zu programmieren sind. Hauptsache schon...
-
- Mit diesen Worten moechte ich mich von euch verabschieden...wuensche euch
- viel Spass beim Sinussen...
-
- Haste Luego
-
- Jeff Kandle
-