          A S S E M B L E R - K U R S       (c)  Jeff Kandle 1991

                                31.Teil...

So, vor einigen Kapiteln habe ich euch ja schon vom VBI erzaehlt, und
seinen Aufbau und seine Aufgaben erzaehlt. Damit habe ich es dann belassen,
weil ich meinte das man ihn zu dem Zeitpunkt noch nicht brauchen wuerde.

Das ist jetzt anders - Wir stehen vor dem Ersten Intro, und da koennen wir
den VBI schon sehr gut gebrauchen, finde ich.

Nochmal kurz zur Erinnerung:
Den VBI fuehrt der Amiga jedesmal auf, wenn der Prozessor das entsprechende
Signal auf seine Leitung bekommt. Das bekommt er jedesmal wenn der
Elektronenstrahl das Vertical Blanking erreicht. Das Vertical Blanking
heisst so, weil dann wenn der Elektronenstrahl diesen Bereich durchquert
nciths auf dem Bildschirm dargestellt wird. Die Bitplane und Sprite DMA ist
dort gesperrt, was dem Prozessor schneller macht. Schon deshalb bietet sich
der VBI gut fuer Zeitaufwendige Routinen an.
Desweiteren spielt das Timing eine Rolle. Der Vorteil der Timingschleife
die wir bis jetzt benutzt haben liegt eindeutig in ihrer kuerze, deswegen
werde ich sie auch weiterhin als beste loesung benutzen. Aber wir gehen die
Schleife ja mit dem Prozessor durch. Wenn wir also in der Schleife noch
eine Menge andere taetigkeiten ausfuehren lassen, dann kann es sehr schnell
vorkommen das diese taetigkeiten, in der Prozessorzeit laenger brauchen als
wie der Elektronenstrahl eine Rasterzeile aufbaut. Das heisst weiter das
der Prozessor abundzu mal eine Zeile nicht `Mitbekommt`. Die Konsequenz
waere dann das es vorkomen koennte das er mal fuer eine 50stel sekunde mit
dem intro nicht weiter macht, und das merkt man schon sehr wohl im
Introgenuss. Beim VBI ist das ja etwas anders, dort kann der Prozessor
seiner aufgetragenen Arbeit folgen, und wird dann von VBI-Signal
unterbrochen.
Er springt dann ueber den Vector der bei $0000006c indirekt an seine
VBI-IRQ-Routine.
Das ist dann der Punkt an den wir uns `Einhaengen` koennen. Das koennen wir
in zwei arten tun.
Wenn wir Taetigkeiten ausfuehren wollen die neben dem normalen
`Amiga-Arbeitstag` erledigt werden sollen, dann muessen wir uns den Wert
der bei $6c liegt merken, den Vector auf unsere Routine verbiegen, und nach
abarbeitung unserer Routine das IRQ-Programm durch einen Sprung, dahin
wohin der Vector zeigte, fortsetzen.
Die zweite Art ist die, die uns interessiert. Dabei merken wir uns
naemlich den Wert der in $6c steht, schreiben die Adresse unserer Routine
dort hin, und lassen es so. Nachdem das Intro/Demo beendet wird, stellen
wir einfach den Vectoor wieder auf den alten Wert, und alles ist wie
vorher.

Hier jetzt mal alle schritte die zur Initialisierung eines eigenen VBI und
der Re-Initialisierung des alten VBI noetig waeren.

Diese Routine ist fuer beide beschriebene Verwendungen tauglich, das sie
die Eingangswerte Dmacon, Intena und den VBI-Vector ($6c) Buffert, und nach
dem Mausclick umrechnen und wieder zurueckschreiben.


Dmacon=         $DFF096
Dmaconr=        $DFF002
Intreq=         $DFF09C
Intena=         $DFF09A
Intenar=        $DFF01C
Ciaapra=        $BFE001

        Move.w  Intenar,Intenabuffer    ; Inhalt von Intena sichern
        Move.w  Dmaconr,Dmaconbuffer    ; Inhalt von Dmacon sichern
        Move.w  #$7fff,Intena           ; Intena loeschen
        Move.w  #$7fff,Dmacon           ; Dmacon loeschen
        Move.l  $006c.w,Oldirq          ; Alten IRQ Vector nach Oldirq
                                        ; retten
        Move.l  #Newirq,$006c.w         ; Adresse von Newirq aus dem Source
                                        ; in den Zeiger schreiben.
        Move.w  #$87e0,Dmacon           ; Alle DMA-Kanaele wieder oeffnen
        Move.w  #$c020,Intena           ; VBI anschalten

; Der VBI ist jetzt Initialisiert und laeuft sofort nach dem Zugriff auf
; Intena.
; Jetzt koennen die Restlichen einstellungen die nichts mit dem VBI zu tun
; haben, erledigt werden.

Wait:                                   ; Auf Maustaste warten (gaehn)
        Btst    #6,Ciaapra
        Bne.s   Wait

; Bevor alle anderen Einstellungen des Intro/Demo geloescht oder auf
; Default zurueckgestellt werden, sollte mit dieser Routine der VBI wieder
; auf den Urspruenglichen Wert zurueckgesetzt werden

        Or.w    #$8000,Intenabuffer     ; Wert im Intenabuffer auf
                                        ; schreibzugriff umformatieren
        Or.w    #$8000,dmaconbuffer     ; Dasselbe !
        Move.w  #$7fff,Intena           ; Intena loeschen
        Move.w  #$07e0,Dmacon           ; Dmacon loeschen
        Move.l  Oldirq,$006c.w          ; Alten Vector von Oldirq nach $6c
        Move.w  Dmaconbuffer,Dmacon     ; Alten Dmaconwert setzen
        Move.w  Intenabuffer,Intena     ; Alten Intenawert setzen
        Moveq   #0,D0                   ; Zur sicherheit (Cli)
        Rts                             ; Auf Wiedersehen!

; Ab hier beginnt die Routine die im VBI ausgefuehrt werden soll
; Die vier Zeilen die dort schon stehen, sollten in jede Routine eingebaut
; werden. Sie garantieren einen Reibungslosen ablauf.

Newirq:
        Move.w  #$0020,Intreq           ; VBI bestaetigen
        Movem.l d0-d7/a0-a6,-(sp)       ; Register auf den Stack retten

; So, hier kann das eigene Programm ablaufen.

        Movem.l (sp)+,d0-d7/a0-a6       ; Register wieder vom Stack holen
        Rte                             ; RTE - Return from Exeption

Oldirq:         dc.l    0
Dmaconbuffer:   dc.w    0
Intenabuffer:   dc.w    0


So, so schwer ist das doch wirklich nicht, oder?
Programmiermaessig kann man damit genauso arbeiten wie mit der
Endlosschleife die wir bis jetzt immer benutzt haben. Allerdings ist sie
halt bei groesseren Intro/Demo-projekten vorzuziehen, da halt alles ein
ganz kleines bisschen schneller geht (nich viel!).
Wichtig ist auch das ihr das RTE am ende nicht mit RTS vertauscht, denn
sonst laeuft das ganze nicht.
Das letzte was ich noch sagen koennte, wisst ihr aber schon. Waehrend des
VBI, der ja eine normale Exeption (Ausnahmezustand) ist, seit ihr im
Supervisor-Modus des Prozessors...Bringt aber bei der
Intro/Demo-Programmiererei nicht viele Vorteile..Ehrlich gesagt kenne ich
gar keine...Hmmh, ich kenn ja auch den Supervisor-Modus nicht so gut..Aber
das ginge auch etwas weit glaube ich.

Am besten probiert ihr mal ein bisschen damit rum, damit ihr ein bisschen
gefuehl fuer die Sache bekommt. Ihr muesst allerdings darauf achten das
ihre den Wert der fuer diese Routine nach Intena und Dmacon geschrieben
wird, eurer Anwendung gerecht sein sollte, da er nicht nur fuer den VBI
gilt, sondern fuer den ganzen Amiga.
Desweiteren muesst ihr aufpassen, damit meine Ich jetzt die, die sich noch
weiter mit anderen Interrupts(Exeptions) befassen wollen, das diese
Routine, da nur fuer den vBI, sehr kurz gehalten werden kann. Eine Routine
die mehrere Interrupts auswerten und durchfuehren kann, wird ungleich
groesser, da jeder Interrupt seine besonderheiten hat, und auch die Zeiten
in denen er auftritt meisst unterschiedlich sind. Ich denke da nur an die
Sprite-Sprite Kollision oder den Diskready Interrupt, sie brauchen genau
wie der VBI die richtigen adressen um ordnungsgemaess arbeiten zu koenen,
sonst laeuft nichts.

Ihr koennt diese Routine auch fuer die Zeitmessung einiger Routinen
benutzen, von der ich im zusammenhang der Optimalen Zeitausnutzung im
letzen Teil gesprochen habe. Ihr muesst dazu einfach die Auszumessende(n)
Routine(n) in den VBI einsetzen, und vor jeder Routine die Bildschirmfarbe
aendern oder eine bestimmte Farbe zuweisen. Dann koennt ihr mit dem
Millimetermass die Zeit in Millimeter (toll, wa) messen. Falls einige von
euch noch mit einem Fernseher oder mit einen schlechten Monitor mit grossem
Bildschirmpumpen habt, dann solltet ihr nicht zu hellen farben verwenden,
oder die Kontraste zwischen den Farben nicht zu gross waehlen, da sonst das
sowieso schon ungenaue Ergebniss nicht noch weiter verschlechtert wird.

So, da dieser Kursteil zwar schon fertig ist, aber noch nicht lang genug
ist zum abschicken, setze ich noch eine Beschreibung des MC 68000 in den
Teil. Sie erklaert die Pin-belegung und eroertert einige Fragen.


                            Der 68000 er

                       ---------------------
                   D4 |1      |      |    64| D5
                   D3 |2      --------    63| D6
                   D2 |3                  62| D7
                   D1 |4                  61| D8
                   D0 |5                  60| D9
                   AS |6                  59| D10
                 -UDS |7                  58| D11
                 -LDS |8                  57| D12
                 R/-W |9                  56| D13
               -DTACK |10                 55| D14
                  -BG |11                 54| D15
               -BGACK |12                 53| GND
                  -BR |13                 52| A23
                  VCC |14                 51| A22
                  CLK |15                 50| A21
                 -GND |16                 49| VCC
                -HALT |17                 48| A20
               -RESET |18                 47| A19
                 -VMA |19                 46| A18
                    E |20                 45| A17
                 -VPA |21                 44| A16
                -BERR |22                 43| A15
                -IPL2 |23                 42| A14
                -IPL1 |24                 41| A13
                -IPL0 |25                 40| A12
                  FC2 |26                 39| A11
                  FC1 |27                 38| A10
                  FC0 |28                 37| A9
                   A1 |29                 36| A8
                   A2 |30                 35| A7
                   A3 |31                 34| A6
                   A4 |32                 33| A5
                       ---------------------

Die Stromversorgung: VCC + GND

Der 68000 arbeitet mit einer einfachen Versorgungssnung von 5 Volt.
Die Anschluesse sind doppelt ausgelegt und zentral gelegen,um durch kurze
Leitungswege im Gehaeuse die Stromverluste minimal zu halten.


Der Takteingang: CLK

Der 68000 benoetigt lediglich einen einfachen Takt.
Die Frequenz haengt von der gewaehlten Prozessorversion ab.
Im Amiga betraegt die Taktfrequenz 7.16 Mhz.


Der Datenbuss: D0 - D15

Der Datenbuss ist als 16-Bit Buss ausgelegt und kann somit ein Wort (16 Bit)
auf einmal uebertragen.Beim Transfer einzelner Bytes ist jeweils nur eine
Haelfte der Leitungen an der Uebertragung beteiligt.
Entweder wird das Byte ueber die unteren 8 Bit oder ueber die oberen 8 Bit
gelesen bzw. geschrieben.


Der Adressbuss: A1 - A23

Der Adressbus kann mit seinen 23 Leitungen 8 Megaworte Speicher ansprechen.
Da er kein A0 besitzt kann er diesen Speicher nur wortweise adressieren.


Bussteuerleitungen im asynchronen Modus: AS,R/-W,UDS,LDS,DTACK

Der 68000 kann seine Speicherzugriffe grundsaetzlich in zwei verschiedenen
Modi ausfuehren. Im asynchronen Modus signalisiert der Prozessor mit AS
(Adress Strobe/Adresse gueltig) dass eine gueltige Adresse am
Adressbus anliegt.Gleichzeitig bestimmt er mit der R/-W (Read-Write/
Lesen-Schreiben) ob ein Byte/Wort gelesen oder geschrieben werden soll.
Die Wahl zwischen Wort oder Byte treffen die Leitungen UDS und LDS.
Da der Speicher immer wortweise adressiert wird,uebertraegt der Prozessor
bei einem Bytezugriff einfach nur die oberen oder die unteren 8 Bits des
Datenbusses.
Dies signalisiert er durch UDS und LDS.Bei einem Wortzugriff legt er beide
Leitungen auf 0.Will er dagegen auf ein Byte zugreifen,legt er entweder
UDS oder LDS auf 0,die andere Leitung auf 1.
Hat der Prozessor jetzt mit AS,R/-W,UDS und LDS den ihm gewuenschten Zugriff
signalisiert,wartet er,bis der Speicher ihm mitteilt,dass die gewuenschten
Daten bereit sind. Dazu verwendet er die Leitung DTACK,die er auf 0 legt
sobald er die Daten bereitgelegt hat.Schreibt der Prozessor die Daten,teilt
ihm der Speicher durch DTACK mit,dass er die Daten uebernommen hat.
Im asynchronen Modus passt sich der Prozessor also immer an die Geschwindigkeit

des Speichers an.


Bussteuersignale im asynchronen Modus: E,VPA,VMA

Um den Sinn dieser Signale besser verstehen zu koennen, muss man die Situation
zum Zeitpunkt der Markteinfuehrung des 68000 kennen. Es waren damals keine
eigenen Periepheriechips fuer den 68000 verfuegbar. Die vorhandenen Chips
von Motorola die ja fuer die 6800-Serie(von der auch der 6502 abstammt)
gedacht waren konnten nicht ohne zusaetzliche Schaltungen in die
asynchrone Bussteuerung eingepasst werden.Also versah man den 68000 bei
Motorola noch mit einem Synchronen Bussmodus,wie man ihn von den 8-Bit
Prozessoren wie dem 6800 oder 6502 kennt.
An der Leitung E liegt staendig ein durch den Faktor 10 geteilter Prozessortakt

an,der den Peripheriechips als Takt dient.
Er wird mit dem Phi-2-Eingang des Chips verbunden.
Die Umschaltung von asynchronem Modus in den synchronen erfolgt ueber den
Eingang VPA (Valid Periphial Adress/Gueltige Peripherieadresse).
Dieser Eingang muss von einem externen Adressdcoder auf 0 gelegt werden,
sobald dieser die Adresse eines Peripheriechips erkennt.Der Prozessor
antwortet darauf indem er die Leitung VMA (Valid Memory Adress/Gueltige
Speiher Adresse) ebenfalls auf 0 legt. Der entsprechende Peripherie-
chip muss jetzt innerhalb eines Taktzyklus von E die Daten uebernehmen
bzw. bereitstellen. Danach verlaesst der 68000 automatisch wieder den
synchronen Modus,bis das VPA Signal erneut aktiv wird.

Dies bedeutet also,dass der Peripheriechip im synchronen Modus
gezwungen ist,die Daten an einem bestimmten Zeitpunkt bereitzustellen bzw. zu
uebernehmen.


bis demnaechst

                Jeff Kandle
