Grafik für Profis

Allen Grafikbegeisterten soll dieser Kurs Tips und Programmierkniffe zum Thema hochauflösende Grafik vermitteln. Wir zeigen Ihnen leistungsstarke Grafik-Routinen mit sehr schnellen Befehlen. Außerdem bekommen Sie ein Programm für 3-D-Grafik.

Wohl jeder Assembler-Alchimist, der gerade das kleine ABC der Maschinensprache kennengelernt hat, wird bei dem Versuch, ein einfaches Basic-Programm in Assembler zu übersetzen, auf nahezu unüberwindliche Schwierigkeiten gestoßen sein. Erfordert doch schon die Multiplikation zweier 16-Bit-Zahlen ein kompliziertes Unterprogramm, so wird der Aufwand bei dem Versuch, den Sinus oder den Logarithmus aus einer Fließkommazahl zu berechnen, geradezu gigantisch. Vorausgesetzt, man will alle erforderlichen Unterprogramme selber schreiben. Glücklicherweise sind die benötigten Routinen jedoch schon im Basic-ROM des C 64 vorhanden. Woran liegt es aber, daß man auf solche Schwierigkeiten stößt, wenn man einen Algorithmus, der sich in Basic relativ einfach bewältigen läßt, in Assembler formulieren will? Nun, die Antwort liegt darin begründet, daß Basic eine sogenannte »höhere« Programmiersprache ist. Die Befehle, die Sie im Wortschatz der Sprache Basic finden, werden Sie im Wortschatz des 6510-Prozessors vergeblich suchen. Das liegt daran, daß jeder einzelne Basic-Befehl sich aus vielen Maschinenbefehlen zusammensetzt. Jedes dieser Maschinenprogramme simuliert praktisch einen Basic-Befehl. Sie werden fragen, was dies alles mit diesem Kurs zu tun hat. Wie Sie der Überschrift entnehmen können, geht es um die Programmierung von hochauflösender Grafik. Auch hier geht es darum, mit Hilfe des 6510-Wortschatzes kompliziertere Befehle aufzubauen, die dazu dienen, Punkte zu zeichnen, Linien zu ziehen etc.

Die meisten dieser Befehle enthalten bestimmte Rechenalgorithmen, die dazu dienen, die Koordinaten eines zu zeichnenden Punktes zu bestimmen. Eine gute Voraussetzung für diesen Grafikkurs sind die beiden Kurse »Reise durch die Wunderwelt der Grafik« und »Assembler ist keine Alchimie« von H. Ponnath. Wenn Sie diese beiden Kurse aufmerksam verfolgt haben, dann sind Sie mit den Grafikfähigkeiten des C 64 vertraut. Mit einigen der dort erworbenen Assemblerkenntnissen dürften Sie wohl in der Lage sein, die zum Zeichnen in der Hi-Res-Grafik wichtigen Befehle selbst in Maschinensprache zu formulieren.

Ein Ergebnis eines solchen Versuchs könnte etwa das Programm »HiRes-3« von H. Ponnath sein. Wenn Sie sich aber eine zeitlang intensiv mit diesem Programm beschäftigt haben, werden Sie merken, daß die Zeichengeschwindigkeit der meisten Befehle noch Wünsche offen läßt. Der Grund hierfür liegt nicht etwa darin, daß das Programm schlecht programmiert wurde, sondern das Problem liegt in der Berechnung der Algorithmen. Das betrifft besonders die Befehle, die mit der herkömmlichen 16-Bit-Arithmetik scheinbar nicht mehr zu bewältigen sind (Circle-Befehl). Gerade hierin aber zeigt sich die wahre Programmierkunst. Nämlich die Fähigkeit, mit einigen Programmierkniffen und mit etwas Fantasie das scheinbar Unmögliche doch noch möglich zu machen. Ich möchte versuchen, Ihnen in diesem Kurs einige dieser »Tricks« zu vermitteln. Dazu eignet sich meiner Änsicht nach nichts besser als das reizvolle Thema »Hochauflösende Grafik«. Dazu bekommen Sie nebenbei auch noch ein professionelles Grafikprogramm, mit dem es sich hervorragend arbeiten läßt. Ich möchte Ihnen nun dieses Programm, das der Hauptgegenstand dieses Kurses sein wird, etwas genauer vorstellen. »Profi-Grafik 64«, so der Name des Programms, besteht aus vielerlei Grafikroutinen, die der besseren Handhabung wegen zu einer Basic-Erweiterung zusammengefaßt wurden. Profi-Grafik 64 hat einige hervorstechende Merkmale:

Nachdem ich Ihnen hoffentlich ein wenig den Mund wässrig gemacht habe, wollen wir nun mit der Besprechung des Programms beginnen.

In dieser Folge finden Sie ein ziemlich langes Assemblerprogramm (Listing 1) sowie ein MSE-Listing (Listing 2). Dieses Listing bildet den Grundstock für eine Basic-Erweiterung und hat eigentlich nichts mit den Grafikroutinen zu tun. Deshalb tippen Sie dieses Listing am besten erst mal ab und speichern es.

Schauen Sie sich nun einmal das Assemblerlisting an. Sie finden dort die Routinen der ersten neun Befehle von Profi-Grafik 64. Ihre Aufgabe ist es vor allem, die hochauflösende Grafik einzuschalten und die Parameter für andere Zwischenbefehle zu setzen. Die Befehle, die sich auf die Hardware beziehen, möchte ich so kurz wie möglich behandeln, weil deren Theorie schon ausführlich im Grafikkurs von H. Ponnath behandelt wurde.

1. SCREEN nr.

Da wäre als erstes der SCREEN-Befehl.

Durch ihn bestimmt man die Nummer des Bildschirms, den man anwählen will. Der Parameter »nr.« kann 0 oder 1 sein. Die Bitmap von Screen0 nimmt den Bereich von $A000-$BFFF ein und das Video-RAM den Bereich von $8C00-$8FFF.

Bei Screenl sind dies die Bereiche $E000-$FFFF für die Bitmap und $CC00-$CFFF für das Video-RAM.

Übrigens wird im Register »Scrnum« nicht die Nummer selbst abgelegt, wie man denken könnte, sondern das High-Byte der Bitmap-Anfangsadresse.

Dies ist deshalb möglich, weil die Bytes $AO und $EO bei einer Bit-Abfrage die Flags unterschiedlich beeinflussen. Dies wird beispielsweise beim HiRes-Befehl ausgenutzt.

2. HIRES

Der Befehl dient nur dazu, den Bildschirm, der mit SCREEN festgelegt wurde, einzuschalten. Das Zustandekommen der einzelnen Werte, mit denen die VIC-Register versorgt werden, soll in der nächsten Folge dieses Kurses beschrieben werden. Ganz Ungeduldige können im H. Ponnaths Grafikkurs, Ausgabe 7/84 nachschauen.

3. MULTI

Schaltet den Multicolormodus ein. Ansonsten wie HIRES.

4. TEXT

Stellt die ursprünglichen Werte in den VIC-Registern wieder her, schaltet also auf den Textbildschirm zurück. Dieser Befehl wird auch bei jedem Warmstart (Programmende) und bei einem Druck auf die RUN/STOP-Taste ausgeführt. Man kann die Grafikbefehle also nur im Programm-Modus verwenden. Der Vorteil dabei ist, daß bei einer Fehlermeldung automatisch in den Text-Modus geschaltet wird.

5. CLEAR

Dieser Befehl löscht die Bitmap des mit SCREEN angewählten Bildschirms.

6. HICOL zf,hf(,c3)

Der Befehl HICOL setzt die Farben im Video-RAM des mit SCREEN angewählten Bildschirms. Im HiRes-Modus brauchen nur die Parameter »zf« und »hf« für Zeichenfarbe und Hintergrundfarbe angegeben werden. Folgt noch ein Komma, so wird der Parameter »c3« geholt und damit das FarbRAM gefüllt. Dieser Parameter braucht nur im Multicolor-Modus angegeben zu werden. Dann gelten die drei Parameter als Zeichenfarben 1, 2 und 3.

7. MODE m

Dieser Befehl gestattet es, die Wirkungsweise des PLOT-Befehls zu beeinflußen. Der Parameter »m« darf zwischen 0 und 2 liegen, wobei bedeuten: 0 = Punkt setzen 1 = Punkt löschen 2 = Punkt invertieren Damit der PLOT-Befehl zwischen den einzelnen Modi unterscheiden kann, wird das Register »Plotmode« durch einen Bit-Befehl abgefragt. Dabei gilt folgende Definition:
0 = Punkt setzen (Z-Flag gesetzt)
64 = Punkt löschen (V-Flag gesetzt)
128 = Punkt invertieren (N-Flag gesetzt)
Das Register »Plotmode« wird im MODE-Befehl 0 entsprechend gesetzt.

8. INK co

Dieser Befehl ist nur im Multicolor-Modus wirksam. Mit ihm wird die Zeichenfarbe festgelegt. Der Parameter »co« darf zwischen 0 und 3 liegen, wobei 0 = Hintergrundfarbe bedeutet. Die Farbe wird im Register »Multicol« abgelegt.

9. PLOT x,y

So, nun endlich kommen wir zum ersten interessanten Befehl, bei dem die Rechnerei in Maschinensprache anfängt.

Der PLOT-Befehl dient dazu, ein Bit in der Bitmap, das durch die Koordinaten »x« und »y« festgelegt wird, zu setzen, zu löschen oder zu invertieren. Die x-Koordinate darf sich dabei zwischen 0 und 319 bewegen, die y-Koordinate zwischenO und 199, wobei der Ursprung des Koordinatensystems in der linken oberen Bildschirmecke liegt. Nun ist es, wie Sie wohl wissen, nicht so einfach herauszufinden, welches Bit in welchem Byte zu einer bestimmten Bildschirmkoordinate gehört. Um das festzustellen, müssen wir uns den Aufbau der Bitmap anschauen (Bild 1).

Schematische Darstellung des Bitmap-Aufbaus mit 40 Spalten und 25 Zeilen
Bild 1. Aufbau der Bitmap: die Anfangsadresse liegt bei 8192; die Punkte zeigen die einzelnen Positionen auf dem Bildschirm

Sie sehen, daß die ersten acht Byte untereinander liegen, die nächsten acht rechts daneben und so weiter, insgesamt 40 Spalten mal 8 Byte = 320 Byte. Im gleichen Stil sind 25 Zeilen untereinander aufgebaut. Das ergibt zusammen 25 mal 320 Byte = 8000 Byte. Der Bildschirmaufbau hat also große Ähnlichkeit mit dem des Textbildschirms. Nun gilt es, einen Algorithmus zu finden, der uns zu einer Bildschirmkoordinate x, y das entsprechende Byte in der Bitmap sowie die Bitposition innerhalb dieses Bytes liefert. Überlegen wir uns zunächst, wie sich die x-Koordinate auf die Byte-Position auswirkt. Wir müssen hier zwischen HiRes- und Multicolor-Grafik unterscheiden. Während im HiRes-Modus jedes Bit einem Punkt entspricht, benötigt man im Multicolor-Modus zwei Bits, um einen Punkt darzustellen. Deshalb gibt es dort nur 160 Punkte auf der x-Achse. Die Tabellen 1 und 2 zeigen, wie sich x-Koordinate und Byte-Nummer in der Bitmap zueinander verhalten, wenn wir die y-Koordinate gleich 0 setzen.

Tabelle mit x-Werten und zugehörigen Bytenummern im HiRes-Modus
Tabelle 1. So verhalten sich die x-Werte und die Bytenummer zueinander bei y=0
Tabelle mit x-Werten und zugehörigen Bytenummern im Multicolor-Modus
Tabelle 2. Multicolor-Modus: x-Werte und Bytenummer für y=0

Sie sehen, daß im HiRes-Modus die unteren drei Bit für die Byte-Nummer unwichtig sind und deshalb gelöscht werden müssen. Dies geschieht mit der AND-Funktion:
xlo and #^11111000

Da die x-Werte größer als 255 sein können, müssen wir auch ein Highbyte berücksichtigen, bei dem allerdings nur das Bit 0 gesetzt sein kann, weil der höchste x-Wert319 = $013Fist. Fürdie HiRes-Grafik sähe der vorläufige Algorithmus also so aus:
256 * xhi+(xlo and #248)

Da es im Multicolor-Modus nur 160 x-Werte gibt, brauchen wir dort kein Highbyte zu berücksichtigen. Sie sehen in Tabelle 2, daß beim Lowbyte die unteren zwei Bit keine Rolle spielen und gelöscht werden müssen: xlo and #%11111100

Mit dieser Berechnungsweise würden wir allerdings nur auf eine maximale Byte-Nummer von 156 kommen. Der Punkt würde also anstatt am rechten Bildrand in der Bildschirmmitte gesetzt. Deshalb müssen alle Byte-Nummern noch mit 2 multipliziert werden, um die richtige Byte-Nummer zu erhalten:
2 * (xlo and #252)

Wie wirkt sich nun die y-Koordinate auf die Byte-Nummer aus?

Wenn diese nicht größer als 7 wird, kann sie direkt zur Byte-Nummer addiert werden. Wird y größer als 7, gelangen wir in eine neue Bildschirmzeile und müssen jeweils 320 Byte addieren. Um zu ermitteln, in welcher Zeile wir sind, müssen wir y durch 8 teilen und gelangen so zur Formel:
(y and #7) +320 * (y/8)

Damit hätten wir die beiden Algorithmen zusammen. Sie lauten:
1. Hires-Modus:
Byte-Nummer = 256 * xhi + (xlo and #248) + (Y and #7) + 320 * (Y/8)
2. Multi-Modus:
Byte-Nummer = 2 * (xlo and #252) + (Yand #7) + 320 * (Y/8)

Nun kommen wir zur Formulierung in Maschinensprache. Dazu legen wir erst fest, wie wir der Berechnungsroutine die Koordinaten übergeben. Und zwar soll der y-Wert im x-Register und der x-Wert in den Registern $14/$15 übergeben werden. Schauen sie sich nun die Routine »Hiplot« im Assemblerlisting an. Dies ist die Unterroutine zur Berechnung der Byte-Nummer im HiRes-Modus. Das Geheimnis der Routine liegtin der Art, wie der Term 320*y/8 berechnet wird. Diese Möglichkeit besteht allerdings nur dann, wenn der Multiplikant (320) konstant und der Multiplikator (y/8) in einem gewissen Bereich (hier 0 bis 24) schwankt. In so einem Fall berechnet man alle möglichen Ergebnisse vorher und legt diese in zwei Tabellen (Low- und Highbyte) ab. In der Berechnungsroutine braucht man dann nur noch den Multiplikator als Zeiger ins y-Register zu übertragen und lädt sich das benötigte Ergebnis aus der Tabelle. Hier sind die Ergebnisse in den Tabellen »Maltab« für die Lowbyte und »Maltabl« für die Highbyte abgelegt. Entscheidend bei der Berechnungsroutine ist weiterhin die Anordnung der einzelnen Summanden. Achten Sie außerdem immer auf den Zustand des Carry-Flags, das für die Addition wichtig ist! Die Nummer des Bytes in der Bitmap wird in den beiden Byte $F7/$F8 abgelegt. Am Ende der Routine wird noch die Bitposition innerhalb des Bytes errechnet. Dazu isolieren wir die x-Position mittels (xlo and # 7) und laden den Akku mit der Zweier-Potenz, die der x-Position entspricht. Diese Zweier-Potenzen sind ebenfalls in einer Tabelle (Hochtab) abgelegt.

Im Multi-Modus sieht das Feststellen der Bitposition etwas anders aus. Da wir hier nur vier x-Positionen in einem Byte haben, isolieren wir diese mittels (xlo and # 3). Dann laden wir den Akku mit dem Wert, bei dem die beiden Bits, die dieser x-Position entsprechen, gesetzt sind. Für die x-Position 0 wäre dies der Wert %11000000. Die vier Werte finden Sie in der Tabelle »Multab«.

Jetzt kommen wir zur Besprechung der PLOT-Routine an sich. Nachdem die Koordinaten aus dem Basic-Text geholt wurden, wird auf Multicolor-Modus geprüft. Dann verlaufen in beiden Teilzweigen der Routine (HPLOT und MPLOT) die Wege ähnlich. Zuerst werden die Koordinaten auf ihre Richtigkeit überprüft. Falls sie den zulässigen Bereich überschreiten, wird die Routine frühzeitig mit gesetztem Carry-Flag verlassen. Ansonsten wird in den Unterroutinen »Hiplot« oder »Muplot« die Byte-Nummer berechnet und die Bit-Position im Akku bereitgestellt. Nun wird das Register »Plotmode« mittels BIT-Befehl abgefragt und je nach Modus verzweigt. Die einzelnen logischen Verknüpfungen machen Sie sich am besten an Hand von Beispielen klar (ausprobieren!).

Zu erklären bleibt noch, wie ein Punkt im Multicolor-Modus gesetzt wird. Sie sehen, daß, nachdem die Bit-Position auf den Stack gerettet wurde, die betreffenden beiden Bits erst einmal gelöscht werden. Dann wird die Bit-Position wiedergeholt und die aktuelle Zeichenfarbe ins x-Register geladen. Sodann wird das Bit-Muster der momentanen Farbe hergestellt, indem es mit dem Bit-Muster der aktuellen Farbe AND-verknüpft wird. Die Bit-Muster der Farben stehen in einer Tabelle »Multab«. Sie erkennen, daß das Bit-Muster an allen vier x-Positionen steht. Versuchen Sie nun herauszufinden, warum die beiden Bits zuerst gelöscht werden müssen, bevor das Muster der neuen Farbe gesetzt werden kann!

Am Ende der Plot-Routine wird dann noch das Carry-Flag gelöscht, um anzuzeigen, daß die Koordinaten in Ordnung waren. Außer den Grafikbefehlen steht Ihnen auch noch ein Mini-Toolkit zur Verfügung. Zum einen ein OLD-Befehl, mit dem Sie ein versehentlich gelöschtes Programm wiederholen können sowie ein AUTO-Befehl, der die automatische Zeilennumerierung übernimmt. Dazu geben sie ein: AUTO Zeilennummer, Schrittweite (0-255). Verlassen können Sie den AUTO-Modus durch Drücken von »RETURN« bei einer neuen Zeile. Trifft der AUTO-Befehl auf eine schon vorhandene Zeile, so wird hinter der Zeilennummer ein Pfeil nach links ausgegeben. Geben Sie danach nur RETURN ein, wird die Zeile nicht überschrieben. Wollen Sie die Zeile überschreiben, dann ist vorher der Pfeil zu löschen.

Eingabehinweise

Listing 2 ist zunächst mit dem MSE einzugben und zu speichern. Im Anschluß daran muß der C 64 aus- und wieder eingeschaltet werden. Laden Sie nun einen Assembler, tippen den Quellcode (Listing 1) ab, lassen ihn übersetzen und laden anschließend Listing 2 absolut (LOAD »PG-MSE«, 8,1). Jetzt muß der Speicherbereich von $800 bis $8574 mit einem Monitorgespeichertwerden. Das Programm läßt sich nun mit SYS 64738 aktivieren.

(Andreas Schömann/cg)
990 open1,4
995 sys 9*4096
1000 .opt oo,p1
1005 ;
1010 ;grafikroutinen 'profi-grafik 64'
1015 ;
1020 *= $8390           ;startadresse
1025 ;
1030 getcom   = $aefd ;prueft auf komma
1035 getbyte  = $b79e ;holt byte ins x-register
1040 getadr   = $b7eb ;adresswert nach $14/$15 + getbyte
1045 chrget   = $0073 ;holt naechstes zeichen
1050 chrgot   = $0079 ;holt letztes zeichen
1055 illegal  = $b248 ;fehlermeldung 'illegal quantity'
1060 ;
1065 scrnum   = $9ff1 ;aktuelle bildschirmnummer
1070 ;
1075 screen jsr getbyte
1080 cpx #2
1085 bcc scrok
1090 jmp illegal
1095 scrok lda scrtab,x
1100 sta scrnum       ;merken
1105 rts
1110 ;
1115 scrtab .byt $a0,$e0
1120 ;
1125 hires lda $dd00        ;16k-bereich,den der vic adressiert
1130 and #%11111100   ;festlegen $c000-$ffff
1135 bit scrnum
1140 bvs *+4          ;bei $e0 ist das v-flag gesetzt !
1145 ora #%00000001   ;bereich von $8000-$bfff
1150 sta $dd00
1155 lda $d018        ;position des videorams
1160 ora #%00101000   ;festlegen $0c00-$0fff
1165 sta $d018
1170 jsr tex1
1175 lda $d011        ;einzelpunktmodus einschalten
1180 ora #%00100000   ;bit5=1
1185 sta $d011
1190 rts
1195 ;
1200 multi jsr hires        ;hires-modus ein
1205 lda $d016        ;multicolormodus einschalten
1210 ora #%00010000   ;bit4=1
1215 sta $d016
1220 rts
1225 ;
1230 text lda $dd00        ;vic adressiert jetzt wieder
1235 ora #%00000011   ;bereich von $0000-$3fff
1240 sta $dd00
1245 lda $d018        ;videoram ab $0400-$07ff
1250 and #%11010111
1255 sta $d018
1260 lda $d011        ;einzelpunktmodus abschalten
1265 and #%11011111
1270 sta $d011
1275 tex1 lda $d016        ;multicolormodus abschalten
1280 and #%11101111
1285 sta $d016
1290 rts
1295 ;
1300 help = $20          ;hilfszeiger
1305 ;
1310 clear lda scrnum
1315 sta help+1
1320 lda #0
1325 sta help         ;zeiger auf anfang der bitmap
1330 tay
1335 ldx #32          ;32 bloecke = 8 kbyte
1340 cloop sta (help),y     ;byte loeschen
1345 iny
1350 bne cloop
1355 inc help+1       ;naechster block
1360 dex
1365 bne cloop
1370 rts
1375 ;
1380 hicol jsr getbyte      ;zeichenfarbe holen
1385 stx help         ;merken
1390 jsr getcom
1395 jsr getbyte      ;hintergrundfarbe
1400 stx help+1       ;merken
1405 lda help         ;zeichenfarbe
1410 asl a
1415 asl a            ;mal 16
1420 asl a
1425 asl a
1430 clc
1435 adc help+1       ;+ hintergrundfarbe
1440 jsr hic1         ;mit diesem wert videoram fuellen
1445 jsr chrgot
1450 cmp #","         ;wenn noch ein komma folgt,
1455 bne mode-1
1460 jsr chrget
1465 jsr getbyte      ;dann 3.zeichenfarbe holen
1470 txa
1475 ldx #$d8         ;und das farbram ($d800-$dfff)
1480 bne hic2         ;damit fuellen
1485 ;
1490 hic1 bit scrnum
1495 bvs scr1a
1500 ldx #$8c         ;screen0 videoram von $8c00-$8fff
1505 .byt $2c          ;bit-opcode
1510 scr1a ldx #$cc         ;screen1 videoram von $cc00-$cfff
1515 hic2 stx help+1
1520 ldy #0
1525 sty help         ;zeiger auf anfang videoram
1530 ldx #4           ;4 bloecke sind zu fuellen
1535 hloop sta (help),y
1540 iny
1545 bne hloop
1550 inc help+1       ;naechster block
1555 dex
1560 bne hloop
1565 rts
1570 ;
1575 plotmode = $9ff2        ;aktueller plotmodus
1580 ;
1585 mode jsr getbyte
1590 cpx #3
1595 bcc modeok
1600 illmode jmp illegal
1605 modeok lda modetab,x
1610 sta plotmode     ;modus merken
1615 rts
1620 ;
1625 modetab .byt 0,64,128
1630 ;
1635 multicol = $9ff3        ;zeichenfarbe fuer multi
1640 ;
1645 ink jsr getbyte      ;zeichenfarbe setzen
1650 cpx #4
1655 bcs illmode      ;>=4, dann fehler
1660 stx multicol     ;merken
1665 rts
1670 ;
1675 xlo = $14
1680 xhi = $15
1685 ;
1690 ;bytenummer errechnen (hires-modus)
1695 hiplot lsr       ;y-koord. schon im akku !
1700 lsr              ;(y/8)
1705 lsr
1710 tay              ;ins y-register
1715 clc              ;alle lobytes addieren
1720 txa
1725 and #%00000111   ;(y and #7)
1730 adc maltab,y     ;+ (320*y/8)lo (c=0!)
1735 sta $f7
1740 lda xlo
1745 and #%11111000   ;+ (xlo and #248)
1750 adc $f7
1755 sta $f7          ;nach $f7
1760 ;addition der hibytes
1765 lda maltab1,y    ;(320*y/8)hi
1770 adc scrnum       ;+ anfang bitmap
1775 adc xhi          ;+ xhi
1780 sta $f8          ;nach $f8
1785 lda xlo          ;bitposition errechnen
1790 and #%00000111   ;(xlo and #7)
1795 tay
1800 lda hochtab,y    ;2^(7-yregister)
1805 rts
1810 ;
1815 muplot lsr             ;(y/8)
1820 lsr
1825 lsr
1830 tay
1835 lda xlo
1840 and #%11111100   ;(xlo and #252)
1845 asl                    ;mal 2 (bit7 ins carry !)
1850 sta $f7          ;nach $f7
1855 lda maltab1,y    ;(320*y/8)hi
1860 adc scrnum       ;+anfang bitmap
1865 sta $f8          ;nach $f8
1870 txa
1875 and #%00000111   ;(y and #7)
1880 adc maltab,y     ;+(320*y/8)lo
1885 tay              ;ins y-register
1890 lda xlo          ;bitposition errechnen
1895 and #%00000011   ;(xlo and #3)
1900 tax
1905 lda multab,x     ;bitwert laden
1910 sec
1915 rts
1920 ;
1925 plot jsr getadr       ;koordinaten holen
1930 lda $d016
1935 and #%00010000
1940 bne mplot        ;multicolormodus
1945 cpx #200
1950 bcs plot-1       ;ykoord.>199 (c=1)
1955 ldy xhi
1960 beq ok
1965 dey
1970 bne plot-2       ;xhi>1 (c=1)
1975 lda xlo          ;xhi=1, dann xlo testen
1980 cmp #<320
1985 bcs plot-1       ;xlo>$40 (c=1)
1990 ok sei
1995 lda #$34         ;speicher auf ram umschalten
2000 sta 1            ;um bit-map lesen zu koennen
2005 txa
2010 pha              ;y-koord. merken
2015 jsr hiplot       ;bytenummer berechnen
2020 ldy #0
2025 bit plotmode
2030 bvs loesch
2035 bmi invert
2040 ora ($f7),y      ;punkt setzen
2045 bne store        ;unbedingter sprung
2050 ;
2055 mplot cpx #200
2060 bcs plot-1
2065 lda xhi          ;xhi<>0 (c=1)
2070 bne plot-2
2075 lda xlo
2080 cmp #160
2085 bcs plot-2       ;xlo>159 (c=1)
2090 sei
2095 lda #$34         ;speicher auf ram umschalten
2100 sta 1
2105 txa
2110 pha              ;ykoord. merken
2115 jsr muplot       ;bytenummer errechnen
2120 bit plotmode
2125 bvs loesch
2130 bmi invert
2135 pha              ;punkt setzen
2140 eor #255         ;vorher loeschen
2145 and ($f7),y
2150 sta ($f7),y
2155 ldx multicol     ;zeichenfarbe laden
2160 pla
2165 and multab1,x    ;bitmuster der farbe setzen
2170 ora ($f7),y
2175 bne store
2180 loesch eor #255         ;punkt loeschen
2185 and ($f7),y
2190 .byt $2c
2195 invert eor ($f7),y      ;punkt invertieren
2200 store sta ($f7),y      ;bitmuster setzen
2205 pla              ;ykoord. wiederherstellen
2210 tax
2215 plotend lda #$37         ;normale speicherkonfiguration
2220 sta 1
2225 cli
2230 clc                    ;c=0 wenn punkt gesetzt
2235 rts
2240 ;
2245 maltab .byt 0,<320,<640,<960 ;multiplikationstabelle
2250 .byt $00,$40,$80,$c0  ;mal 320
2255 .byt $00,$40,$80,$c0  ;lobytes
2260 .byt $00,$40,$80,$c0
2265 .byt $00,$40,$80,$c0
2270 .byt $00,$40,$80,$c0
2275 .byt $00
2280 ;
2285 maltab1 .byt 0,>320,>640,>960
2290 .byt $05,$06,$07,$08  ;mal 320
2295 .byt $0a,$0b,$0c,$0d  ;hibytes
2300 .byt $0f,$10,$11,$12
2305 .byt $14,$15,$16,$17
2310 .byt $19,$1a,$1b,$1c
2315 .byt $1e
2320 ;
2325 hochtab .byt $80,$40,$20,$10 ;zweierpotenzen
2330 .byt $08,$04,$02,$01
2335 ;
2340 multab .byt %11000000    ;xposition0
2345 .byt %00110000    ;xposition1
2350 .byt %00001100    ;xposition2
2355 .byt %00000011    ;xposition3
2360 ;
2365 multab1 .byt %00000000    ;farbe0=hintergrund
2370 .byt %01010101    ;farbe1
2375 .byt %10101010    ;farbe2
2380 .byt %11111111    ;farbe3
Listing 1. Die ersten neun Befehle von »Profi-Grafik 64«.
PROGRAMM : PG-MSE         8000 8390
-----------------------------------
8000 : 20 80 09 80 C3 C2 CD 38   AD
8008 : 30 20 BC F6 20 E1 FF D0   09
8010 : 0C 20 76 80 20 A3 FD 20   31
8018 : 18 E5 20 7B E3 4C 72 FE   03
8020 : 20 A3 FD 20 90 FD 20 76   FC
8028 : 80 20 5B FF 58 A2 0B BD   D1
8030 : 8E 80 9D 00 03 CA 10 F7   1C
8038 : 20 BF E3 A0 0F A9 00 99   B6
8040 : F0 9F 88 10 FA 85 37 85   E8
8048 : 33 A9 80 85 38 85 34 A9   F4
8050 : A0 8D F1 9F A9 5A A0 82   1C
8058 : 20 1E AB 20 30 E4 20 6F   00
8060 : 82 A2 FB 9A 20 D2 83 8A   41
8068 : 30 03 4C 3A A4 4C 74 A4   3C
8070 : 20 D2 83 4C 83 A4 20 15   6C
8078 : FD A9 9A 8D 24 03 A9 80   A4
8080 : 8D 25 03 A9 22 8D 26 03   C3
8088 : A9 81 8D 27 03 60 64 80   00
8090 : 70 80 3B 81 FE 81 33 82   0D
8098 : 86 AE A5 99 F0 03 4C 66   37
80A0 : F1 A5 D3 85 CA A5 D6 85   4A
80A8 : C9 AD F0 9F D0 03 4C 32   33
80B0 : E6 8A D0 31 18 AD FE 01   23
80B8 : 65 FE 85 14 AD FF 01 69   32
80C0 : 00 85 15 20 13 A6 08 A6   A0
80C8 : 14 A5 15 20 CD BD 28 90   85
80D0 : 07 A9 5F 20 D2 FF D0 05   02
80D8 : A9 20 20 D2 FF A9 00 A4   8A
80E0 : D6 85 CA 84 C9 20 32 E6   F0
80E8 : 08 48 C9 5F D0 14 A5 14   DF
80F0 : 8D FE 01 A5 15 8D FF 01   B1
80F8 : 68 28 A9 0D 20 D2 FF 4C   B2
8100 : 7B A4 C9 0D D0 19 A4 C8   DB
8108 : 88 30 0C B1 D1 C9 3A B0   97
8110 : 0E C9 30 90 0A B0 F1 A9   62
8118 : 00 8D F0 9F 4C 74 A4 68   DB
8120 : 28 60 48 A5 9A C9 03 F0   25
8128 : 03 4C D5 F1 AD 11 D0 29   FE
8130 : 20 D0 04 68 4C 16 E7 68   AC
8138 : 4C 16 E7 A6 7A A0 04 84   24
8140 : 0F BD 00 02 10 07 C9 FF   CF
8148 : F0 3E E8 D0 F4 C9 20 F0   AB
8150 : 37 85 08 C9 22 F0 55 24   CC
8158 : 0F 70 2D C9 3F D0 04 A9   02
8160 : 99 D0 25 C9 30 90 04 C9   0F
8168 : 3C 90 1D 84 71 A0 00 84   E9
8170 : 0B 88 86 7A CA C8 E8 BD   C2
8178 : 00 02 38 F9 9E A0 F0 F5   65
8180 : C9 80 D0 2F 05 0B A4 71   C1
8188 : E8 C8 99 FB 01 C9 00 F0   FA
8190 : 38 38 E9 3A F0 04 C9 49   8F
8198 : D0 02 85 0F 38 E9 55 D0   76
81A0 : A0 85 08 BD 00 02 F0 E0   52
81A8 : C5 08 F0 DC C8 99 FB 01   94
81B0 : E8 D0 F0 A6 7A E6 0B C8   AE
81B8 : B9 9D A0 10 FA B9 9E A0   A3
81C0 : D0 B5 F0 0F BD 00 02 10   8D
81C8 : BD 99 FD 01 C6 7B A9 FF   E0
81D0 : 85 7A 60 A0 00 B9 EF 82   51
81D8 : D0 02 C8 E8 BD 00 02 38   4D
81E0 : F9 EF 82 F0 F5 C9 80 D0   E1
81E8 : 04 05 0B D0 99 A6 7A E6   D2
81F0 : 0B C8 B9 EE 82 10 FA B9   B3
81F8 : EF 82 D0 E0 F0 C6 10 0F   1C
8200 : 24 0F 30 0B C9 FF F0 07   88
8208 : C9 CC B0 06 4C 24 A7 4C   41
8210 : F3 A6 38 E9 CB AA 84 49   58
8218 : A0 FF CA F0 08 C8 B9 EF   16
8220 : 82 10 FA 30 F5 C8 B9 EF   DB
8228 : 82 30 05 20 47 AB D0 F5   09
8230 : 4C EF A6 20 73 00 20 3C   52
8238 : 82 4C AE A7 C9 CC 90 04   CE
8240 : C9 F5 90 06 20 79 00 4C   4F
8248 : ED A7 38 E9 CC 0A AA BD   97
8250 : A0 82 48 BD 9F 82 48 4C   C3
8258 : 73 00 93 12 20 50 52 4F   5F
8260 : 46 49 2D 47 52 41 46 49   5A
8268 : 4B 20 36 34 20 20 00 A9   2E
8270 : 01 A8 91 2B 20 33 A5 18   F1
8278 : A5 22 69 02 85 2D A5 23   68
8280 : 69 00 85 2E 4C 63 A6 20   CB
8288 : EB B7 86 FE 38 A5 14 E5   9D
8290 : FE 8D FE 01 A5 15 E9 00   DF
8298 : 8D FF 01 EE F0 9F 60 6E   AD
82A0 : 82 86 82 8F 83 A0 83 C5   CF
82A8 : 83 D1 83 F2 83 09 84 51   88
82B0 : 84 65 84 BC 84 00 00 00   E8
82B8 : 00 00 00 00 00 00 00 00   B9
82C0 : 00 00 00 00 00 00 00 00   C1
82C8 : 00 00 00 00 00 00 00 00   C9
82D0 : 00 00 00 00 00 00 00 00   D1
82D8 : 00 00 00 00 00 00 00 00   D9
82E0 : 00 00 00 00 00 00 00 00   E1
82E8 : 00 00 00 00 00 00 00 4F   87
82F0 : 4C C4 41 55 54 CF 53 43   31
82F8 : 52 45 45 CE 48 49 52 45   BB
8300 : D3 4D 55 4C 54 C9 54 45   C8
8308 : 58 D4 43 4C 45 41 D2 48   5F
8310 : 49 43 4F CC 4D 4F 44 C5   54
8318 : 49 4E CB 50 4C 4F D4 00   18
8320 : 00 00 00 00 00 00 00 00   21
8328 : 00 00 00 00 00 00 00 00   29
8330 : 00 00 00 00 00 00 00 00   31
8338 : 00 00 00 00 00 00 00 00   39
8340 : 00 00 00 00 00 00 00 00   41
8348 : 00 00 00 00 00 00 00 00   49
8350 : 00 00 00 00 00 00 00 00   51
8358 : 00 00 00 00 00 00 00 00   59
8360 : 00 00 00 00 00 00 00 00   61
8368 : 00 00 00 00 00 00 00 00   69
8370 : 00 00 00 00 00 00 00 00   71
8378 : 00 00 00 00 00 00 00 00   79
8380 : 00 00 00 00 00 00 00 00   81
8388 : 00 00 00 00 00 00 00 00   89
Listing 2. MSE-Listing: Der erste Teil einer Basic-Erweiterung.
PDF Diesen Artikel als PDF herunterladen
Mastodon Diesen Artikel auf Mastodon teilen
← Vorheriger ArtikelNächster Artikel →