Der Display-List-Interrupt#
von Uwe Röder, CSM APRIL 1990
Diese Folge des Assembler-Lehrganges ist im Grunde genommen eine Neuauflage aus meiner Serie über die Fähigkeiten unseres Ataris.
Da ich in der letzten Ausgabe auf die Programmierung von Display-Lists eingegangen bin, dachte ich, dass nun unbedingt auch die Programmierung des Display-List Interrupts folgen muss.
Der Display-List-Interrupt dient dazu, während des Bildschirmaufbaus den Bildschirm betreffende Daten zu verändern.
Dies ist wohl die allgemeinste Definition. Konkret bedeutet dies für mich als Programmierer, dass ich praktisch nach jeder Bildschirmzeile einen neuen Zeichensatz, neue Farben usw. benutzen kann.
Bei solchen einfachen Dingen, wie dem Umschalten eines Zeichensatzes oder dem Ändern der Hintergrundfarbe bedarf es im Grunde nur der elementarsten Befehle: LDA und STA
Daran kann man schon erkennen wie einfach das Programmieren eines DLIs ist.
Es gibt nur wenige Voraussetzungen, die erfüllt werden müssen, um einen DLI zu benutzen.
Eine Grundbedingung ist, dass in der entsprechenden Zeile in der Display-List nach der der DLI ausgelöst werden soll Bit 7 gesetzt ist. Dies wurde ja schon letzten Monat deutlich gemacht.
Wenn ich eine bereits existierende Display-List im Speicher nachträglich DLI-tauglich machen will, kann ich dies durch eine 'Oderierung' des entsprechenden Bytes mit $80 (128) erreichen.
Danach muss die Adresse der Interrupt-Routine in VSDLST $200,$201 (512,513) eingetragen werden und letztlich muss ich noch Bit 7 in NMIEN $D40E (54286) setzen, damit der DLI auch ausgeführt wird. In aller Regel muss hier also $C0 (192) eingetragen werden. Bei der DLI-Routine ist noch zu beachten, dass die Registerinhalte (A,X,Y) vor und nach Aufruf der Routine identisch sein müssen, um einen System-Absturz zu vermeiden. Das heißt, dass die Registerinhalte direkt zu Beginn der Routine auf dem Stapel oder wo auch immer abgelegt werden und ganz am Ende der Routine wieder zurückgeholt werden müssen.
Eine weitere (nicht zwingende) Bedingung ist das Arbeiten mit WSYNC $D40A. Schreibt man vor dem Ändern einer Adresse einen Wert in WSYNC so wartet der Computer bis zum Beginn der nächsten Bildschirmzeile und nimmt erst dann die Änderung vor. Würde man beim Farbenumschalten auf diesen Vorgang verzichten, so kann es zu einem Flackern der Farbe im Umschaltbereich führen.
Im übrigen ist es noch wichtig, dass man direkt die Hardwareregister verändert, da ein Umändern der Schattenregister erst nach dem vollständigen Aufbau des Bildschirms sichtbar wird!
Als Beispiel für die Hardwareregister seien hier die wichtigsten für den DLI kurz angegeben:
Farbregister: 708-712 ($2C4-$2C8)
Hardwareregister: 53270-53274 ($D016-$D01A)
Zeichensatz: 756 ($2F4)
Hardwareregister: 54281 ($D409)
Es ist weiterhin zu beachten, dass die Routine, die durch den DLI aufgerufen wird, nicht allzu lang ist, da sonst Probleme bei zeitkritischen Input/ Output Operationen entstehen können. So kann zum Beispiel der Diskettenzugriff trotz Speedy und High-Speed-SIO unendlich langsam werden oder gar ganz den Geist aufgeben.
Sie finden im Anhang noch einige Beispiele dazu, doch will ich hier einmal ein sehr allgemeines Beispiel geben:
00010 .LI OFF 00020 ------------------------------ 00030 WSYNC .EQ $D40A 00040 VSDLST .EQ $200 ;DLI-VEKTOR 00050 SDLST .EQ $230 ;DL-VEKTOR 00060 NMIEN .EQ $D40E 00070 COLOR .EQ $D018 00080 ADR .EQ $D0 00090 ------------------------------ 00100 START LDA SDLST 00110 STA ADR 00120 LDA SDLST+1 00130 STA ADR+1 00140 ------------------------------ 00150 LDY #16 00160 ;POSITION DES BYTES IN DL 00170 ------------------------------ 00180 LDA (ADR),Y 00190 ORA #$80 00200 STA (ADR),Y 00210 ;BIT 7 IN DL SETZEN 00220 ------------------------------ 00230 LDA #0 00240 STA NMIEN 00250 ;INTERRUPTS SPERREN 00260 ------------------------------ 00270 LDA #DLI 00280 STA VSDLST 00290 LDA /DLI 00300 STA VSDLST+1 00310 ;DLI-ADRESSE IN VEKTOR 00320 ------------------------------ /00330 LDA #$C0 00340 STA NMIEN 00350 ;INTERRUPTS FREIGEBEN 00360 ------------------------------ 00370 RTS 00380 ;FERTIG ! 00390 ------------------------------ 00400 DLI PHA 00410 TXA 00420 PHA 00430 TYA 00440 PHA 00450 ;REGISTER AUF STAPEL RETTEN 00460 ------------------------------ 00470 LDA #$30 00480 STA WSYNC 00490 ;FLACKERN VERMEIDEN 00500 STA COLOR 00510 ;BELIEBIGE AENDERUNGEN ... 00520 ------------------------------ 00530 PLA 00540 TAY 00550 PLA 00560 TAX 00570 PLA 00580 ;REGISTER ZURUECKHOLEN 00590 ------------------------------ 00600 RTI 00610 ;ENDE DES DLI 00620 ------------------------------Sie müssen sich also nur an das folgende einfache Schema halten:
- Bit 7 in Display-List setzen
- Interrupt sperren; NMIEN=0
- DLI-Adresse in VSDLST eintragen
- Interrupt freigeben; NMIEN=$C0
In der DLI-Routine ist nur zu beachten, dass die Prozessor-Register gerettet und nur die Hardwareregister verändert werden. Um Flackern von Farben etc. zu vermeiden, sollte vor einer Farbänderung ein beliebiger Wert in WSYNC geschrieben werden.
Also alles ganz einfach!!!
Ich hoffe, Sie kommen mit allem klar. Wenn irgendwelche Unklarheiten existieren experimentieren Sie doch einfach mit den DEMO-Programmen. Sie sind im Bibo-Assemblerformat im Anhang.
Anahng#
Beispiel 1 (DLI1.ASM)#
00010 .LI OFF 00020 ------------------------------ 00030 WSYNC .EQ $D40A 00040 VSDLST .EQ $200 ;DLI-VEKTOR 00050 SDLST .EQ $230 ;DL-VEKTOR 00060 NMIEN .EQ $D40E 00070 COLOR .EQ $D018 00080 ADR .EQ $D0 00090 ------------------------------ 00100 START LDA SDLST 00110 STA ADR 00120 LDA SDLST+1 00130 STA ADR+1 00140 ------------------------------ 00150 LDY #16 00160 ;POSITION DES BYTES IN DL 00170 ------------------------------ 00180 LDA (ADR),Y 00190 ORA #$80 00200 STA (ADR),Y 00210 ;BIT 7 IN DL SETZEN 00220 ------------------------------ 00230 LDA #0 00240 STA NMIEN 00250 ;INTERRUPTS SPERREN 00260 ------------------------------ 00270 LDA #DLI 00280 STA VSDLST 00290 LDA /DLI 00300 STA VSDLST+1 00310 ;DLI-ADRESSE IN VEKTOR 00320 ------------------------------ 00330 LDA #$C0 00340 STA NMIEN 00350 ;INTERRUPTS FREIGEBEN 00360 ------------------------------ 00370 RTS 00380 ;FERTIG ! 00390 ------------------------------ 00400 DLI PHA 00410 TXA 00420 PHA 00430 TYA 00440 PHA 00450 ;REGISTER AUF STAPEL RETTEN 00460 ------------------------------ 00470 LDA #$30 00480 STA WSYNC 00490 ;FLACKERN VERMEIDEN 00500 STA COLOR 00510 ;BELIEBIGE AENDERUNGEN ... 00520 ------------------------------ 00530 PLA 00540 TAY 00550 PLA 00560 TAX 00570 PLA 00580 ;REGISTER ZURUECKHOLEN 00590 ------------------------------ 00600 RTI 00610 ;ENDE DES DLI 00620 ------------------------------
Beispiel 2 (DLI2.ASM)#
00010 .LI OFF 00020 ------------------------------ 00030 VDSLST .EQ $200 00040 SDLSTL .EQ $230 00050 DL .EQ $D0 00060 COLOR .EQ $D018 00070 WSYNC .EQ $D40A 00080 VCOUNT .EQ $D40B 00090 UHR .EQ $14 00100 COLOR2 .EQ $D01A 00110 ------------------------------ 00120 S LDY #0 00130 LDA SDLSTL 00140 STA DL 00150 LDA SDLSTL+1 00160 STA DL+1 00170 LDA (DL),Y 00180 ORA #$80 00190 STA (DL),Y 00200 LDA #0 00210 STA $D40E 00220 LDA #DLI 00230 STA VDSLST 00240 LDA /DLI 00250 STA VDSLST+1 00260 LDA #$C0 00270 STA $D40E 00280 LDA #$E 00290 STA $2C5 00300 RTS 00310 ------------------------------ 00320 DLI PHA 00330 TXA 00340 PHA 00350 TYA 00360 PHA 00370 ------------------------------ 00380 LDA #$50 00390 STA WSYNC 00400 STA COLOR2 00410 LDA #0 00420 STA COLOR 00430 .1 LDA VCOUNT 00440 CMP #$30 00450 BCC .1 00460 LDA #$30 00470 STA COLOR 00480 .2 LDA VCOUNT 00490 CMP #$50 00500 BCC .2 00510 LDA #$19 00520 STA COLOR 00530 ------------------------------ 00540 .3 PLA 00550 TAY 00560 PLA 00570 TAX 00580 PLA 00590 RTI 00600 ------------------------------
Beispiel 3 (DLI3.ASM)#
00010 .LI OFF 00020 ------------------------------ 00030 COLOR .EQ $D018 00040 VCOUNT .EQ $D40B 00050 WSYNC .EQ $D40A 00060 ADR .EQ $D0 00070 ------------------------------ 00080 S LDA $230 00090 STA ADR 00100 LDA $231 00110 STA ADR+1 00120 LDY #2 00130 LDA (ADR),Y 00140 ORA #$80 00150 STA (ADR),Y 00160 LDY #12 00170 LDA (ADR),Y 00180 ORA #$80 00190 STA (ADR),Y 00200 LDY #$14 00210 LDA (ADR),Y 00220 ORA #$80 00230 STA (ADR),Y 00240 LDA #6 00250 LDX /VBI 00260 LDY #VBI 00270 JSR $E45C 00280 LDA #$E 00290 STA $2C5 00300 RTS 00310 ------------------------------ 00320 VBI LDA #0 00330 STA $D40E 00340 LDA #DL1 00350 STA $200 00360 LDA /DL1 00370 STA $201 00380 LDA #$C0 00390 STA WSYNC 00400 STA $D40E 00410 LDA #$90 00420 STA $2C8 00430 JMP $E45F 00440 ------------------------------ 00450 DL1 PHA 00460 LDA #0 00470 STA WSYNC 00480 STA COLOR 00490 LDA #DL2 00500 STA $200 00510 LDA /DL2 00520 STA $201 00530 PLA 00540 RTI 00550 ------------------------------ 00560 DL2 PHA 00570 LDA #$30 00580 STA WSYNC 00590 STA COLOR 00600 LDA #DL3 00610 STA $200 00620 LDA /DL3 00630 STA $201 00640 PLA 00650 RTI 00660 ------------------------------ 00670 DL3 PHA 00680 LDA #$A0 00690 STA WSYNC 00700 STA COLOR 00710 LDA #DL1 00720 STA $200 00730 LDA /DL1 00740 STA $201 00750 PLA 00760 RTI 00770 ------------------------------
Beispiel 4 (DLI4.ASM)#
00010 .LI OFF 00020 ------------------------------ 00030 VDSLST .EQ $200 00040 SDLSTL .EQ $230 00050 DL .EQ $D0 00060 COLOR .EQ $D018 00070 WSYNC .EQ $D40A 00080 VCOUNT .EQ $D40B 00090 UHR .EQ $14 00100 COLOR2 .EQ $D01A 00110 ------------------------------ 00120 S LDY #0 00130 LDA SDLSTL 00140 STA DL 00150 LDA SDLSTL+1 00160 STA DL+1 00170 LDA (DL),Y 00180 ORA #$80 00190 STA (DL),Y 00200 LDA #0 00210 STA $D40E 00220 LDA #DLI 00230 STA VDSLST 00240 LDA /DLI 00250 STA VDSLST+1 00260 LDA #$C0 00270 STA $D40E 00280 LDA #$E 00290 STA $2C5 00300 RTS 00310 ------------------------------ 00320 DLI PHA 00330 TXA 00340 PHA 00350 TYA 00360 PHA 00370 ------------------------------ 00380 LDA #$50 00390 STA WSYNC 00400 STA COLOR2 00410 LDA #0 00420 STA COLOR 00430 .1 LDA VCOUNT 00440 CMP #$30 00450 BCC .1 00460 LDA #$30 00470 STA COLOR 00480 .2 LDA VCOUNT 00490 CMP #$50 00500 BCC .2 00510 LDA #$19 00520 STA COLOR 00530 ------------------------------ 00540 .3 PLA 00550 TAY 00560 PLA 00570 TAX 00580 PLA 00590 RTI 00600 ------------------------------