DEN C64'er AUSGEREIZT (Teil 3)
INTERRUPTKURS
Bevor Sie weiterlesen, sollten Sie zuerst das Demo " THINK TWICE" auf SEITE 2 einladen und versuchen sich ein bißchen
Gedanken zu machen über die Effekte, die
einem hier geboten werden.
Was Sie hier sehen, vermittelt einem den
Eindruck, als würden die Graphikreihen
einzeln und unabhängig von einader ins
Bild hüpfen, um sich im Takt der Musik
zu einer Graphik zusammenzusetzen.
Um es gleich mal vorwegzunehmen, dieser
interessante Bildaufbau wird nur durch
einfaches Austricksen des VIDEO-Chips
realisiert und NICHT durch irgendeine
programmiertechnische Akrobatik.
Kern des Demos und unser heutiges Thema
ist eine kleine Routine, die den meisten
Freaks als ' Flexible-Line- Distance' oder
kurz FLD bekannt sein müßte.
DIE FLD-ROUTINE
Wie wir wissen, verfügt der C64' er über
einen Textbildschirm, der sich aus 25 ZEILEN mit jeweils 40 SPALTEN zusammensetzt. Wer die Bezeichnung ' Flexible-Line- Distance' richtig übersetzt, der
kann sich vielleicht vorstellen, was mit
dieser Routine alles möglich ist.
Die Programmierergruppe' The Judges' hat
meiner Meinung nach als erste einen Weg
gefunden, den Zeilenabstand auf einfache
Weise zu beeinflussen.
Wer sich das Auswahlmenü der MAGIC DISK
etwas genauer angeschaut hat, dem ist es
vielleicht aufgefallen, daß beim Drücken
von RETURN, der ganze Bildschirm herauf
und herunter geschoben wird.
Dies ist der einfachste Effekt, der mit
FLD realisierbar ist. Es wurde einfach
der Abstand zwischen Zeile $00 und allen
weiteren Zeilen verändert. Wie das Ganze
im einzelnen abläuft, wird anhand des
folgenden Source-Listings erläutert.
;***** FLD-DEMO 1 ***** 1000 SEI ;IRQ sperren 1001 LDA #$7F ;Timer-Interrupt 1003 STA $DC0D ;abschalten!!! 1006 LDA $DC0D ;ICR löschen 1009 LDA #$F8 ;Rasterzeile $f8 als 100B STA $D012 ;IRQ-Auslöser festlegen 100E LDA $D011 ;Bit 7 (Hi-Position) 1011 AND #$7F ;löschen 1013 STA $D011 1016 LDA #$01 ;Raster als IRQ-Quelle 1018 STA $D01A ;wählen 101B LDX #$78 ;IRQ-Vektor auf 101D LDY #$10 ;Interrupt Routine Nr.2 101F STX $0314 ;richten 1022 STY $0315 1025 LDA #$00 ;Zeilenabstand 1027 STA $02 1029 LDA #$FF ;Striche 102B STA $3FFF 102E CLI ;IRQ freigeben 102F RTS 1030 LDA #$10 ;die ersten drei 1032 STA $D011 ;Bits löschen 1035 LDA $02 ;Zeilenabstand in Akku 1037 BEQ $105E ;wenn = 0, dann Abbruch 1039 LDX #$00 ;Zähler auf Null 103B CLC ;*Beginn der Schleife* 103C LDA $D011 103F ADC #$01 ;Wert 1 addiren 1041 AND #$07 ;erste 3 Bits sondern 1042 ORA #$10 ;Screen On 1045 STA $D011 ;abwärts scrollen 1048 DEC $D019 ;IRR löschen 104B JSR $102F ; 12 Taktzyklen 104E JSR $102F ; 12 Taktzyklen 1051 LDA $D012 ;Rasterstrahl auslesen 1054 CMP #$F6 ;letzte Zeile erreicht? 1056 BEQ $105E ;Ja?? Dann Abbruch 1058 INX ;Zähler erhöhen 1059 CPX $0002 ;FLD zu Ende 105C BNE $103B ;Rücksprung 105E LDA #$F8 ;Rasterzeilen $f8 als 1060 STA $D012 ;IRQ-Auslöser festlegen 1063 DEC $D019 ;IRR löschen 1066 LDA #$78 ;IRQ-VEKTOR auf 1068 STA $0314 ;Adresse $1078 umstellen 106B LDX #$0E ;Rahmen und Bildfarbe 106D LDY #$06 ;auf blau stellen 106F STX $D020 1072 STY $D021 1075 JMP $FEBC ;Sprung zu IRQ-Ende ;--------------------------------------- 1078 LDA #$10 ;24 Zeilen 107A STA $D011 107D LDA #$71 ;Rasterzeile 9*8+41 = $71 107F STA $D012 ;als IRQ-Auslöser für FLD 1082 DEC $D019 ;IRR-löschen 1085 LDA #$30 ;IRQ-VEKTOR auf 1087 STA $0314 ;Adresse $1030 umstellen 108F LDA $DC00 ;Joy-Stick PORT 2 1092 LSR ;prüfen ob BIT 1 gelöscht 1093 BCS $1097 ;NEIN?? dann verzweigen 1095 DEC $02 ;Zeilenabstand verringern 1097 LSR ;prüfen ob BIT 2 gelöscht 1098 BCS $109C ;NEIN?? dann verzweigen 109A INC $02 ;Zeilenabstand erweitern 109C JMP $EA31 ;Sprung zu IRQ-Ende
Laden Sie nun " FLD-DEMO 1" von SEITE 2 und starten Sie wie immer mit SYS4096 .
Was diese Routine bewirkt, kommt erst
dann zutage, sobald Sie ein paar Zeichen
in den unteren Teil des Bildes schreiben
und den Hebel am Joy-Stick nach unten
drücken.
Zwischen den Zeilen 8 und 9 erscheint
eine schwarze Linie, die per Joy-Stick
variierbar ist und das gesamte Bild nach
unten wegschiebt. Den Abstand zwischen
den Zeilen kann man auch mit POKE2, X beeinflussen.
Die Routine erlaubt aber noch viel mehr
Experimente:
Es ist möglich diesen Abstand zwischen
jede der 25 Zeilen zu legen. Beim auswählen der Zeilen sollte man am besten
die folgende Formel anwenden:
POKE4222, X*8+41 Für X müssen Sie einen Wert zwischen 0 und 24 einsetzen, der anschließend mit
8 multipliziert wird, da man den IRQ nur
jede achten Rasterzeile auslösen darf.
Den schwarze Streifen kann man auch beeinflussen, indem man einen Wert zwischen
0 bis 255 in das letzte Byte eines jeden
16 Kbyte Bereiches schreibt. In unserem
Fall ist es die Adresse #16383($3 fff) .
Allerdings wurde bis heute noch keine
Möglichkeit gefunden die Farbe dieser
Streifen irgendwie zu ändern. Sie bleiben
immer schwarz. Wen das stört, der kann
sie mit POKE16383,0 ganz abschalten Weitere interessante Effekte kann man
erzeugen, wenn man FLD in Verbindung mit
Hochauflösender Graphik benutzt.
Nach diesem aufregenden Beispiel sollen
Sie nun endlich mit der Funktionsweise
der Routine bekannt gemacht werden.
Die Initialisierung zu erläutern sparen
wir uns einfach, denn das haben wir bereits in der letzten Ausgabe hinter uns
gebracht. Kommen wir also gleich zu den
ersten Befehlen der FLD-Routine.
Gleich zu Beginn wird ein Wert aus $02 in den Akku geladen. Ist der geladene
Wert gleich 0, so erfolgt ein Sprung zum
Ende der Routine.
Das Verschieben der Bildteile haben wir
mit einer ganz gewöhnlichen Schleife
realisiert, wobei der Wert in Adresse $2 maßgeblich ist, für die Breite der Spalte
und die Anzahl der Schleifendurchläufe.
Ein einziger Durchlauf verbraucht genau
63 Taktzyklen.
Das eigentliche ' Herz' der FLD-Routine
sind die nun folgenden Befehle.
CLC LDA $D011 ADC #$01 AND #$07 ORA #$10 STA $D011
Selbst erfahrenen FLD-Programmierern, dürfte diese Befehlsfolge noch nicht be- kannt sein. Ich habe absichtlich einen
umständlicheren Weg gewählt, weil man das
grundlegende Prinzip der FLD mit dieser
Methode leichter erklären kann.
Doch zum besseren Verständnis dieser
Befehle, müssen wir uns ( leider) wieder
einmal mir der Hardware befassen.
Wie wir wissen setzt sich ein normaler
Bildschirm aus 25 CHARAKTER-Zeilen mit
jeweils 40 Zeichen zusammensetzt. Schon
im letzten Kurs haben wir erfahren, daß
das Erstellen der CHARAKTER-ZEILEN vom
VIC-Chip geregelt wird. Zu diesem Zweck
wird der CPU jede achte Rasterzeilen für
exakt 42 Taktzyklen unterbrochen.
Wir wissen weiterhin, daß der VIC-Chip
genaustens darüber informiert ist, welche
Rasterzeile vom Elektronenstrahl gerade
aufgebaut wird. Zusätzlich muß er die
aktuelle Rasterposition mit den ersten
drei Bits im Register $ D011 vergleichen.
Diese Bits sind fürs vertikale scrollen
erforderlich und können die Position der
CHARAKTER-Zeilen direkt beeinflussen.
Auf diese recht komplizierte Weise, ist
es dem VIC-CHIP möglich, die richtigen
Rasterzeilen zu ermittelt, um CHARAKER-Zeilen aufzubauen.
Normalerweise wird das alles intern geregelt. Eine Möglichkeit, daß der Programmierer darauf Einfluß nehmen oder
überhaupt daran beteiligt sein könnte, ist vom Hersteller nicht vorgesehen.
Allerding hat COMMODORE hierbei nicht
mit dem zähen Durchhaltevermögen der
Freaks gerechnet, die sich auf die wehrlosen Chips stürzten, sie gnadenlos
austricksten und alle Vorkehrungen buchstäblich auf den Kopf stellten.
Haben Sie sich eigentlich schon überlegt, was passiert, wenn man den Bildschirm mit den ersten 3 Bits aus $ D011 bitweise abwärts bewegt ? ? Richtig, der
Elektronenstrahl würde solange über den Bildschirm fahren, bis er eine CHARAKTER-Zeile findet. Und genau auf dieser
Theorie basiert FLD.
Widmen wir uns nun wieder dem Source-Listing. Die FLD-Routine wird jedesmal
durch einen IRQ angesprungen, der direkt
unter der vorhergehenden CHARAKTER-Zeile
ausgelöst wurde.
Der eigentliche Schleifenbeginn ist bei
Adresse $103 B. Nachdem wir das CARRYFLAG
gelöscht haben, laden wir $ D011 und
addieren den Wert 1 dazu. Gleich danach
folgt ein AND #$07, weil nur die ersten
3 Bits für uns interessant sind. Der Befehl ORA #$10 sorgt dafür, daß der Bildschirm eingeschaltet bleibt. Die Bitkombination, die sich nun ergeben hat, schreiben wir wieder zurück in $ D011 .
Der FLD-Effekt entsteht dadurch, daß
die CHARAKER-Zeilen die ganze Zeit vor
dem Rasterstrahl hergeschoben werden.
Es werden nun so lange Leerzeilen oder
schwarze Striche gemalt, bis der Rasterstrahl auf eine CHARAKTER-ZEILE trifft.
Und das wird erst dann passieren, sobald
unsere Schleife abgelaufen ist.
Auf der Diskette befinden sich noch
weitere Demos zum Thema FLD.
In " FLD-ROUTINE 2" wird eine wesenlich
praktischere Befehlsfolge verwendet.
LDA $D012 AND #$07 ORQ #$10 STA $D011
Diese Programmzeilen sieht man in der
Praxis am häufigsten. Hierbei wird das
Raster-Register $ D012 als Zähler eingesetzt. Außerdem kann man zwischen den
Zeilen noch Rastereffekte darstellen.
" FLD-ROUTINE 3" wurde noch einfacher
programmiert. Von der ursprünglichen
Routine sind nur noch 2 Befehle übriggeblieben.
LDA $1200, X STA $ D011
Sämtliche erforderlichen Werte werden
hier aus einer Tabelle geholt.
Wer neugierig ist zu erfahren, wie der
Bildaufbau in' THINK-TWICE' gemacht wird, der sollte sich einfach " FLD-ROUTINE 4" anschauen. Hier ist es nämlich möglich, den Abstand zwischen allen Zeilen zu
beeinflussen. Zu diesem Zweck müssen Sie
einfach einen Wert zwischen 0 und 200 in
die Adressen $1000-$1019 schreiben.
DAS TAKTZYKLEN-PROBLEM
Wie Sie sicher schon gemerkt haben, sind
die RASTER-Routinen des letzten Kurses
und die heutigen FLD-Routinen nur durch
ein spezielles TIMING realisierbar.
Diese Tatsache kann sich aber leicht zu
einem unüberwindlichen Hindernis entwickeln, wenn man über eine erforderliche
TAKTZYKLEN-LISTE nicht verfügt.
Diejenigen, die bereits vor diesem Problem gestanden haben, wird das nächste
Programm sicher weiterhelfen.
;**** ZYKLEN-MESSER **** 1000 SEI 1001 LDY #$00 ;Bildschirm aus 1003 STY $D011 1006 CPY $D012 1009 BNE $1006 100B DEY 100C STY $DD04 ;TIMER Werte 100F STY $DD05 ;setzen 1012 LDA #$11 1014 STA $DD0E ;TIMER-starten 1017 DEC $D019 ;==> ASSEMBLER-BEFEHL
101 A SEC 101 B LDA #$ FA ; vergangene Zyklen 101 D SBC $ DD04 ; abziehen 1020 STA $0 FFF ; Taktzyklen speichern 1023 JMP $ FCE2 ; RESET
Diese Programm mißt mit Hilfe der CIAs,
die Taktzyklen der Befehle.
Alles was Sie tun müssen, ist den entsprechenden Befehl an die Adresse $1017 zu setzen und mit SYS4096 starten
Die Taktzyklen erhalten Sie nach einem
? PEEK (4095)
In unserem Testprogramm haben wir den
Befehl ' DEC $ D019' an die entsprechende
Adresse geschrieben. Starten Sie nun das
Programm auf die beschriebene Weise, so
werden Sie die ZahL 6 als TAKTZYKLENWERT
erhalten Da Sie nun selbst in der Lage sind die
Taktzyklen zu ermitteln, müßte es Ihnen
relativ leicht fallen, die vorgestellten
Source-Listings abzuändern oder zu verbessern.
Eine Bemerkung sollte ich Ihnen noch
auf den Weg Ihrer eigenen Versuche mitgeben: die VIC-Adresse $ D011 ist die
zentrale Schaltstelle im VIDEO-CHIP und somit eine äußerst interessante Adresse.
Wer glaubt, daß die Programmierung von
FLD alles ist, was man aus ihr heraustricksen kann, der irrt sich gewaltig.
Möglicherweise ist Ihnen schon die
mysteriöse Routine im LOADER der MAGIC-DISK aufgefallen, die einen ganzen Hiresbildschirm von oben herabschweben läßt.
Dies ist z. B. nur einer von viele TRICKS
die mit $ D011 möglich sind.
Sie sehen, dieses Register ist wirklich
eine sehr interessante Sache, wenn man
es nur richtig zu nutzen weiß. Befassen
Sie sich ruhig ein wenig damit, es lohnt
sich bestimmt ! !
(IVO HERZEG)