DisplayList für Neueinsteiger #1

Moderator: Rockford

Antworten
Benutzeravatar
Prodehl
Beiträge: 127
Registriert: 24. Aug 2021, 14:40
Has thanked: 3 times
Been thanked: 25 times
Kontaktdaten:

DisplayList für Neueinsteiger #1

Beitrag von Prodehl »

DisplayList #1

Wenn man (so wie ich damals in den 80-igern) Programme in einer Hochsprache entwickelt - damals auf dem Atari 800 z.B. in BASIC, dann ist man nicht unbedingt darauf angewiesen ein tieferes Verständnis der grafischen Bildschirmausgabe zu besitzen. Das BASIC hat bereits entsprechende Befehle integriert und übersetzt am Ende alles in den entsprechenden Maschinencode. So ist es dann einfach z.B. eine „Hallo Welt“- Ausgabe zu programmieren:
10 Print „Hallo Welt“
20 Goto 10

Ein entsprechender Print-Befehl existiert in Assembler nicht und wenn man etwas auf den Bildschirm bekommen möchte, dann stößt man recht bald unweigerlich auf die DisplayList. So erging es auch mir!
Aber was genau passiert denn da? Der Name zunächst ist völlig irreführend, denn es handelt sich dabei gar nicht um eine Bildschirm Liste, sondern um Programmanweisungen eines ganz eigenen Prozessors - dem ANTIC. Vielfach gehört, aber wie genau erzeugt dieser Chip das Bild und wie kann ich das beeinflussen und steuern?

Die Idee eines solchen Prozessors war zwar damals nicht neu, für den Heimcomputerbereich aber schon fast revolutionär. Der ANTIC liest dabei Daten aus dem Hauptspeicher, verarbeitet sie und baut dann entsprechend den Bildschirm auf.
Zusätzlich sorgt der ANTIC-Prozessor auch für die Generierung der Player-/Missile Grafik.
Der Antik kann nur lesen und keine Daten in den Prozessor zurückschreiben, um dieses Problem zu lösen gibt es die Schattenregister…

Die Befehle, die der Anti verarbeiten kann sind eigentlich recht simpel. Es gibt einen Vectorbefehl, wo angegeben ist, wo der Bildschirm anfängt und einen Sprungbefehl, der saget, wo die Displaylist wieder startet. Alle anderen Displaylisteinträge sind keine Befehle im eigentlichen Sinn, sondern stellen nur Werte dar, wie die einzelnen Zeilen aufgebaut werden.

Wenn man jetzt weiß, an welcher Speicherstelle der Bildschirm bei Graphics 0 (in Basic) anfängt, kann man relativ einfach durch ein Poke-Befehl im Basic oder durch LDA / STA in Assembler eine Ausgabe auf den Bildschirm machen:
Zum Experimentieren empfehle ich das in Basic, das kann man dann relativ einfach in Assembler umsetzen:

Poke 40000,33 läßt links oben ein A entstehen, denn dort fängt der Bildschirm im Speicher an… und dieser Anfang wird in der DL festgelegt!

In den Speicherstellen 560 (LoBi) und 561 (HiBi) steht die Adresse des DL:
Print Peek(560)
32
Print Peek(561)
156
Print 32+256*156
39968

Am Beispiel von Graphics 0 fängt die DL also an der Stelle 39968 im Hauptspeicher an.
Hier geht es los mit drei Einträgen 112
? Peek(39968), Peek(39969), Peek(39970)
112 112 112
Das sind die drei schwarzen Zeilen am oberen Rand, die einfach leer sind.
Poke 39968,2 würde eine leere Textzeile am Oberrad erzeugen (die man aber nicht beschreiben kann).

An Stelle 4 des DL (also bei Speicherstelle 39971 kommt ein erster echter Befehl: 64 - dieser benennt die Adresse des Bildschirmstartes mit den zwei folgenden Stellen (Stelle 5 und 6):
Peek(39972) liefert 64 und Peek(39973) liefert 156

64+256*156 ergibt 40000 - also die Startadresse des Bildschirmes.
Will man also die Startadresse des Bildschirmes ändern (wird z.B. scrollen wichtig), dann ändert man einfach diese beiden Adressen entsprechend!

Danach folgen 23 x die Speichereinträge 2 - diese legen letztlich den Textmodus für Graphics 0 fest und danach kommt der Sprungbefehl (65) mit den nachfolgenden beiden Speichereinträgen, die festlegen wohin gesprungen werden soll - nämlich wieder zum Anfang der DL, die ja ständig wiederholt abgearbeitet werden muss.
Warum nur 23x2 ? Wir haben ja 24 Zeilen! Das steckt witzigerweise in Stelle 4 der DL im Befehl mit drin. Der Befehl an Stelle 4 der DL ist eigentlich Dezimal 64, in der Stelle 4 steht aber 66. Hier wird einfach schon die erste zu generierende Zeile zum Befehl addiert. 64+2=66
Ich denke, die Atari-Entwickler wollten damit ein wenig Verwirrung stiften ;-)

Das wars eigentlich schon, was den Aufbau der DL angeht. Im Anhang noch eine schöne Übersicht über die DL bei Graphic 0.

In Teil 2 wird man dann erfahren, was es für Auswirkungen haben kann die DL zu verändern, wie flexibel man alles mischen kann und wie man einfach eigene Grafikmodi erstellen kann.
Dateianhänge
DisplayList.png

Benutzeravatar
Prodehl
Beiträge: 127
Registriert: 24. Aug 2021, 14:40
Has thanked: 3 times
Been thanked: 25 times
Kontaktdaten:

Re: DisplayList für Neueinsteiger #1

Beitrag von Prodehl »

Hier noch kurz mein Listing für "Hallo Welt":

Basic:
10 Print "Hallo Welt"
20 Goto 10

Assembler:

Code: Alles auswählen

10 ;Hallo Welt Demo einfach
20		*= $4000
30		LDA #40
40		STA $9C40
50		LDA #33
60		STA $9C41
70		LDA #44
80		STA $9C42
90		STA $9C43
100		LDA #47
110		STA $9C44
120		LDA #55
130		STA $9C46
140		LDA #37
150		STA $9C47
160		LDA #44
170		STA $9C48
180		LDA #52
190		STA $9C49
200		LDA #00
210		STA $9C45
220		STA $9C4A
Dieser Assemblercode ist hier bewusst ganz einfach gewählt!
Etwas komplexer wird es dann hier:

Code: Alles auswählen

10 ;Hallo Welt Demo Komplex
20		.OPT OBJ
30		*= $4000
40 RET = $9B
50 IOCB = $0340
60 CIOV = $E456
70 DEVICE .BYTE "E:",RET
80 TEXT .BYTE "HALLO WELT!",RET
90		LDX #$20
100		LDA #$03
110		STA $0342,X
120		LDA #DEVICE&255
130		STA $0344,X
140		LDA #DEVICE/256
150		STA $0345,X
160		LDA #$08
170		STA $034A,X
180		LDA #$00
190		STA $034B,X
200		JSR CIOV
210		LDA #$09
220		STA $0342,X
230		LDA #TEXT&255
240		STA $0344,X
250		LDA #TEXT/256
260		STA $0345,X
270		LDA #$00
280		STA $0348,X
290		LDA #$FF
300		STA $0349,X
310		LDA #$FF
320		STA $02FC
330 LP	JSR CIOV
340		LDA $02FC
350		CMP #$FF
360		BNE STOP
370		JMP LP
380 STOP	BRK
390		.END
Das Programm startet nicht bei 4000, sondern bei 400F !!
Man sieht an diesem Beispiel wie komplex die Programmierung einfacher Anwendungen in Assembler werden kann.
Zur Ausgabe von Hallo Welt wurde zudem in diesem Beispiel die CIOV des Ataris benutzt, man könnte den Text natürlich auch direkt auf den Bildschirm ausgeben - was allerdings in diesem Fall etwas weniger elegant ist.
Dies würde dann den Text "Hallo Welt!" quasi Buchstabe für Buchstabe zerlegen und dann in den Bildschirmspeicher direkt kopieren - ähnlich wie im ersten etwas plumpen Listing.
Zuletzt geändert von Prodehl am 3. Sep 2021, 21:37, insgesamt 3-mal geändert.

Benutzeravatar
cas
Beiträge: 54
Registriert: 18. Jun 2021, 21:01
Wohnort: Solar System
Has thanked: 2 times
Been thanked: 9 times
Kontaktdaten:

Re: DisplayList für Neueinsteiger #1

Beitrag von cas »

Prodehl hat geschrieben:
3. Sep 2021, 20:16

Leider macht dieser Editor alle Tabs weg, die müssen natürlich im Assembler rein!
Umschliesse Quellcode mit [ code ] [ /code ] Bloecken (nur ohne die Leerzeichen hinter [ und ]), z.B.:

Code: Alles auswählen

10 ;Hallo Welt Demo einfach
20		*= $4000
30		LDA #40
40		STA $9C40
50		LDA #33
60		STA $9C41
70		LDA #44
80		STA $9C42
90		STA $9C43
[...]
Dann sieht es besser aus ;)
Prodehl hat geschrieben:
3. Sep 2021, 20:16
Wenn man dies jetzt per copy/paste in den Assembler überträgt, dann werden die Anführungszeichen nicht mitkopiert ...
In deinen Beispielen sind typografische Anfuehrungszeichen, wie sie von Textverarbeitungen erzeugt werden. Die kennt der Atari nicht, daher verschwinden die. Ggf. oben im Post durch echte Anfuehrungszeichen "" ersetzen.

Benutzeravatar
Prodehl
Beiträge: 127
Registriert: 24. Aug 2021, 14:40
Has thanked: 3 times
Been thanked: 25 times
Kontaktdaten:

Re: DisplayList für Neueinsteiger #1

Beitrag von Prodehl »

thx ;-)

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste