home *** CD-ROM | disk | FTP | other *** search
- A S S E M B L E R - K U R S (c) Jeff Kandle 1990
-
- 5.Teil...
-
-
- Ne, Leute ich hab mirs ueberlegt, wir arbeiten erstmal ein bisschen mit dem
- Listing was wir schon haben. Wir widmen uns erst einmal einfachen effekten
- mit farben und so. Wir lernen dabei auch erstmal ein paar tolle neue
- Sachen, die man in Assembler machen kann. Kopierroutinen, einfachere
- Zaehlroutinen, und wie man leichte schwingungen (sinusse) von Hand eingibt.
-
- So, jetzt verbessern wir erstmal die Zaehlroutine die wir bei der Sache mit
- der Powerled benutzt hatten, wir machen sie einfacher, und gestalten sie so
- das man sie Wunderbar auch als Zaehlroutine fuer eine Kopieraktion benutzen
- kann...erinnern wir uns, wie hatten wir die Erste Routine gemacht.
-
- Move.w #$5000,d0
- Loop: Sub.w #1,d0
- Bne.s Loop
- Rts
-
- Ungefaehr so sah das doch aus oder...Jetzt habe ich aber einen befehl der
- Das `Sub` und das `Bne` in sich vereinigt
-
- Dbra oder Dbf
-
- Dasselbe programm saehe so aus...
-
- Move.w #$5000,d0
- Loop: Dbf d0,loop
- Rts
-
- So, was macht der Dbf (Dbra)-befehl. Er zaehlt das hinter ihm angegebene
- Rgister eins runter, und verzweigt immer wenn -1 noch nicht erreicht ist,
- das ist der Unterschied zum `Bne` Befehl, denn der Verzweigt ja bekanntlich
- bei 0.
-
- So, jetzt zum Kopieren...das A und O der Intro und Demoschreiberei.
- Allerdings muessen wir noch eine Adressierungsart des Move-befehl`s
- kennenlernen, besser gesagt zwei...aber das seht ihr ja dann.
-
- 8.Indirekte Adressierung
-
- Also, eine weitere schoene Sache ist die Indirekte Adressierung. Es sieht
- so aus, das in der Quell oder Ziel Spalte, nicht die adresse direkt steht,
- sondern nur wo die Adresse steht. Erstmal ein Beispiel mit dem Jmp befehl
-
- Stellt euch vor bei $20000 sieht es so aus
-
- 00 02 a0 00
-
- stellt euch weiter vor irgendwo im SourceCode steht eben jenes Mnemonic
-
- ...
- ...
- ...
- Jmp ($20000)
- ...
- ...
- ...
-
- Was passiert wenn der Prozessor auf diesen Befehl trifft. Er Analysiert den
- Jmp Befehl, sieht das er Indirekt ist. Und holt sich den Wert aus der
- Adresse die bei dem Jmp befehl steht, und legt das Langwort das an dieser
- Adresse zu finden ist in den PC...den rest kennt ihr ja, vonwegen das er da
- jetzt weiterarbeitet und so. Er wuerde also nach $2a000 springen.
-
- Was das mit Kopieren zutun hat ist ganz einfach. Sehen wir uns mal ein
- Routine an die mit unseren Mitteln geschrieben ist, und die 20 Langwoerter
- ab $20000 nach $30000 Kopiert
-
- Move.l $20000,$30000
- Move.l $20004,$30004
- Move.l $20008,$30008
- Move.l $2000c,$3000c
- Move.l $20010,$30010
- Move.l $20014,$30014
- Move.l $20018,$30018
- Move.l $2001c,$3001c
- Move.l $20020,$30020
- Move.l $20024,$30024
- Move.l $20028,$30028
- Move.l $2002c,$3002c
- Move.l $20030,$30030
- Move.l $20034,$30034
- Move.l $20038,$30038
- Move.l $2003c,$3003c
-
-
- Das geht ja an sich noch, und wenn es auf schnelligkeit ankommt, und es
- wirklich `Nur` um 20 Langwoerter handelt kann man es so machen.
- Aber was ist wenn man 128000 bytes Kopieren will, 32000 Zeilen Sourcecode
- ist ein bisschen viel...Also nehmen wir mal die Vorzuege der indirekten
- Adressierung, erst das beispiel mit kurzen Saetzen, und dann die ganze
- sache peinlich genau erklaert, den jetzt ist es sehr wichtig, da die
- indirekte Adressierung sehr wichtig.
-
- Folgendes programm Kopiert ebenfalls 20 langwoerter von $20000 nach $30000
-
- Start: Lea $20000,a0 ; Quell Adresse nach A0
- Lea $30000,a1 ; Ziel Adresse nach A1
- Move.w #19,d0 ; Laenge-1 nach d0, da Dbf bis -1 zaehlt
- Loop: Move.l (a0),(a1) ; Kopiert wert von $20000 nach $30000,
- ; allerdings inidirekt, da ja in A0 und A1
- ; die Zeiger auf die stellen stehen.
- Add.l #4,a0 ; Zeiger in A0 auf naechstes Langwort
- ; stellen.
- Add.l #4,a1 ; A1 ebenfalls
- Dbf d0,loop ; Schon 20 mal, nein -> zurueck
- Rts
-
- So mehr nicht, das prinzip ist klar, oder ?
- Der Vorteil liegt in der Kuerze, denn das programm wird nicht laenger egal
- wieviel ich damit kopiere. Ob 30 langwoerter oder 64 Kilobyte, es bleibt
- dasselbe programm.
-
- Es holt sich erst die Zeiger auf Quell und Ziel bereich in die
- Adressregister 0 und 1, den mit denen kann man auch indirekt arbeiten...
- Dann wird der Counter nach D0 geholt, wie ich gesagt hatte zaehlt der Dbf
- befehl bis minus 1, deshalb muss ich das vorher beruecksichtigen, und die
- laenge direkt -1 nehmen. Nachdem er dann von der Quelle die in A0 steht zum
- Ziel das in A1 steht ein Langwort kopiert erhoeht er die beiden Zeiger so
- dass sie jetzt aus $20004 und $30004 zeigen...usw..nach dem 20.sten
- Durchlauf schmeisst der dbf befehl uns raus indem er ueberlesen wird, und
- dann kommt der Rts befehl......->
-
- Schoen das ist ja recht kurz..aber es geht noch kuerzer
-
- Und zwar mit der Indirekten Postinkrementalen Adressierung, oder
- Rueckwaerts mit der Indirekten Predekrementalen Adressierung.
-
- Hoert sich schwer an, is ess aber nicht...Denn dies Adressierungs art
- uebernimmt nur dieses Add.l #4 im SourceCode, indem sie die Zeiger
- automatisch erhoeht nachdem gelesen und geschrieben wurde. Besser noch, Wir
- muessen gucken was wir dazu addieren, falls wir Woerter kopieren koennen
- wir ja nich plus 4 nehmen, dann wuerden fehler auftreten is ja klar, und
- bei Byte waere es schlimm...Diese Adressierung schaut auch nach was ich
- Kopiert habe, und setzt dementsprechend die Zeiger weiter, das heiss
- Kopiert man Bytes setzt sie die Zeiger auf um 1 (byte) weiter, Kopiert man
- langwoerter wird das entsprechende Register auch um 4 Byte`s (langwort)
- weiter gestellt...Das listing von Eben saehe jetzt so aus
-
- Start: Lea $20000,a0
- Lea $30000,a1
- Move.w #19,d0
- Loop: Move.l (a0)+,(a1)+
- Dbf d0,loop
- Rts
-
- Wird ja immer kuerzer....
-
- So noch schnell die erklaerung der beiden dollen woerter
-
- Post bedeutet `Nachher`, und Inkremental bedeutet erhoehen...Also es wird
- Nachher erhoeht
-
- Pre bedeutet `Vorher`, und Dekremental bedeutet erniedrigen....also es wird
- vorher erniedrigt.
-
- Sinn hat das Vielleicht nicht, aber es ist nuetzlich, besonders wenn sich
- Quell und ziel bereich ueberlappen. Aber hier erstmnal das listing mit den
- Aenderungen wenn es Predekremantal arbeiten soll
-
- Start: Lea $20040,a0 ; Natuerlich muessen wir dann auch ganz
- ; hinten anfangen.
- Lea $30040,a1
- Move.w #19,d0
- Loop: Move.l -(a0),-(a1)
- Dbf d0,loop
- Rts
-
- Alles klor...
-
- So noch eine Kleine Spielerei wenn ihr mal Speicher bereiche Spiegeln
- muesst, bei bilder geht es zwar nicht, da die aus Bitplanes bestehen, aber
- um texte zu spiegeln oder so reicht sie... Man laesst einfach einen zeiger
- ab und den anderen auflaufen, schaut her !
-
- Start: Lea $20000,a0
- Lea $30040,a1
- Move.w #19,d0
- Loop: Move.l (a0)+,-(a1)
- Dbf d0,loop
- Rts
-
- Mit ein bisschen logischem denken koennt ihr euch die funktion ja erklaeren,
- falls nicht muesst ihr euch das kapitel noch mal durchlesen...
-
- Natuerlich kann man mit dieser Geilen Adressierungsart auch noch toll
- loeschen...
-
- Start: Lea $20000,a0
- Clr.l d0
- Move.l #$20000,d0
- Loop: Move.l d0,(a0)+
- Dbf d0,loop
- Rts
-
- ...loescht 128 Kbyte ab $20000.
-
- 9.Weiter mit dem Copper
-
- So, will ich noch ein bisschen mit sogenannten billig effekte aufhalten,
- weil man sie halt immer wieder braucht, zum Beispiel einen balken der von
- oden nach unten zieht.
- Als Grundlage nehme ich unser Ersten Copperlisten Programm damit ihr nicht
- wieder alles neuabtippen muss. Wir werden zwar bald aus diesen SourceCode
- rauswachsen aber im Moment reicht er noch eine Zeit.
-
- Also, gehen wir das erstmal Theoretisch durch, wenn ihr es versteht einfach
- nicken. Dann werden wir das Programm schritt fuer schritt modifiziern..
-
- Nun, wir muessten eigentlich nur die Wait befehle bearbeiten, und zwar nur
- die positionen worauf sie warten, das koennten wir mit add machen, und zwar
- mit add #$100, damit wir die Zeilen Nummer und nicht den Pixel treffen.
- Desweiteren muessen wir natuerlich auch eine Warteschleife einbauen damit
- das auch klappt, und nicht zu schnell geht. Also jetzt kommt das listing un
- alles was Ergaenzt wurde ist gross geschrieben.
-
-
- Execbase = 4
- Openlibrary = -552
- CIAapra = $BFE001
- Cop1lc = $DFF080
- Forbid = -132
- Permit = -138
-
- Start: move.l Execbase,a6 ; Vorbereitungen fuer Forbid und
- ; Openlibrary.
- jsr Forbid(a6) ; Forbid
- clr.l d0 ; Versionsnummer Egal
- lea gfxname,a1 ; Name der zu oeffnenden Lib nach A1
- jsr Openlibrary(a6) ; Graphics.library oeffnen
- move.l d0,gfxbase ; Adresse der Lib merken
-
- move.l #copperliste,Cop1lc ; Adresse der Copperliste nach Cop1lc
-
-
- LEA COPPERLISTE,A0
- MOVE.W #$5000,D0
- Wait: DBF D0,WAIT
- ADD.W #$100,4(a0)
- ADD.W #$100,12(a0)
-
-
- Btst #6,CIAapra ; Kennt ihr schon
- Bne.s wait
-
- Move.l gfxbase,a0 ; Basisadresse nach a0
- Move.l 38(a0),Cop1lc ; 38. sten wert einfach nach Cop1lc
- ; schreiben
- Jsr Permit(a6) ; Multitasking erlauben
- Clr.l d0 ; kein returncode
- Rts
-
- Gfxname: dc.b "graphics.library",0
- even
- Gfxbase: dc.l 0
- Copperliste:
-
- dc.w $0180,$0000
- dc.w $200f,$fffe
- dc.w $0180,$0f00
- dc.w $220f,$fffe
- dc.w $0180,$0000
-
- copperlistenende:
- dc.l $-2 ; ende der copperliste , -2 = $fffffffe
-
- End:
-
- Erstmal die naechste dazugekommene Adressierungsart, es ist die Indirekte
- mit Adressdistanz. Das Heisst, es wird der Angegebene Zeiger genommen, und
- die Adressdistanz dazu gezaehlt. Beispiel
-
- Lea $40000,a0
- Move.l #$23452345,$28(a0)
- Rts
-
- Es wird erst der zeiger $40000 nach a0 geholt, und dann der Wert $234523345
- nach A0 + Distanz geschrieben, das waere dann $40028.
- Warum ich das gemacht habe ?..Nun ich habe in A0 die adresse meiner
- Copperliste gehabt, und dann habe ich nur noch abgezaehlt anwievielter
- stelle die Wait befehle stehen, um sie zu Modifizieren, geschickt, ne?
-
- Modifizieren geschieht ja durch Add.w #$100 wie ihr gesehen habt.
-
- Das mit der Warte schleife ist ansich ja gut so aber wenn man was auf dem
- Bildschirm macht sollte man zu einer anderen loesung greifen, aber dazu das
- Naechste mal...
-
- Have a nice Night
-
- Jeff Kandle
-