!!!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 [VDSLST] $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 ------------------------------
}}}