DEN C64'er AUSGEREIZT (Teil 3)
INTERRUPTKURS -------------
Bevor Sie weiterlesen, sollten Sie zu- erst 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 zusammen- setzt. 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 be- einflussen. Die Routine erlaubt aber noch viel mehr Experimente: Es ist möglich diesen Abstand zwischen jede der 25 Zeilen zu legen. Beim aus- wä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 be- einflussen,indem man einen Wert zwischen 0 bis 255 in das letzte Byte eines jeden 16Kbyte Bereiches schreibt. In unserem Fall ist es die Adresse #16383 ($3fff). 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 be- reits 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 ge- regelt. Eine Möglichkeit, daß der Pro- grammierer 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 wehr- losen Chips stürzten, sie gnadenlos austricksten und alle Vorkehrungen buch- stäblich auf den Kopf stellten. Haben Sie sich eigentlich schon über- legt, was passiert, wenn man den Bild- schirm 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 $103B. 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 Be- fehl ORA #$10 sorgt dafür, daß der Bild- schirm eingeschaltet bleibt. Die Bitkom- bination, 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 Raster- strahl 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 einge- setzt. 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 übrig- geblieben. 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 ent- wickeln,wenn man über eine erforderliche TAKTZYKLEN-LISTE nicht verfügt. Diejenigen, die bereits vor diesem Pro- blem 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
101A SEC 101B LDA #$FA ;vergangene Zyklen 101D SBC $DD04 ;abziehen 1020 STA $0FFF ;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 ent- sprechenden 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 ver- bessern. Eine Bemerkung sollte ich Ihnen noch auf den Weg Ihrer eigenen Versuche mit- geben: 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 heraus- tricksen kann, der irrt sich gewaltig. Möglicherweise ist Ihnen schon die mysteriöse Routine im LOADER der MAGIC- DISK aufgefallen,die einen ganzen Hires- bildschirm 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)