Basic Plot / Drawto in Assembler
Moderator: Rockford
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Basic Plot / Drawto in Assembler
Ich stelle das Thema mal online zur Diskussion:
Eine Assemblerroutine maximal schnell und effektiv um ein Plot/Drawto in Antic D nachzubilden...
Ideen??
Eine Assemblerroutine maximal schnell und effektiv um ein Plot/Drawto in Antic D nachzubilden...
Ideen??
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... ich lege mal los ...
- wir brauchen wohl den Bresenham-Algorithmus.
Im Grunde ganz einfach: Beim Zeichnen einer Geraden von Punkt A zu Punkt B hat man ja letztlich eine Steigung der Geraden. Man plottet im Grunde immer in eine Richtung - nämlich in die lange Achse und entscheiden dann (anhand der Steigung) ab und zu mal einen Punkt in die kurze Achse zu plotten und geht dann von da weiter. Das lässt sich dann in eine Routine umsetzen.
- wir brauchen wohl den Bresenham-Algorithmus.
Im Grunde ganz einfach: Beim Zeichnen einer Geraden von Punkt A zu Punkt B hat man ja letztlich eine Steigung der Geraden. Man plottet im Grunde immer in eine Richtung - nämlich in die lange Achse und entscheiden dann (anhand der Steigung) ab und zu mal einen Punkt in die kurze Achse zu plotten und geht dann von da weiter. Das lässt sich dann in eine Routine umsetzen.
-
- Beiträge: 194
- Registriert: 19.08.2021 00:18
- Has thanked: 23 times
- Been thanked: 68 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Lies mal den Artikel "Schnelle Vektoren in Action!" aus ATARIMAGAZIN von P.Finzel.
Dort beschreibt er einen Algorithmus, der schneller ist als die OS Routine.
https://atariwiki.org/wiki/Wiki.jsp?pag ... ARImagazin
Dort beschreibt er einen Algorithmus, der schneller ist als die OS Routine.
https://atariwiki.org/wiki/Wiki.jsp?pag ... ARImagazin
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... vielen Dank. Sehr interessanter Artikel (wie immer bei Peter Finzel). Leider in Action! geschrieben.
Action! ist sicherlich eine höchst interessante Sprache, die ich leider nicht nutze. Vielleicht kann man das mal irgendwie in Eclipse implementieren - das wäre doch was für Peter (JAC)?!
Action! ist sicherlich eine höchst interessante Sprache, die ich leider nicht nutze. Vielleicht kann man das mal irgendwie in Eclipse implementieren - das wäre doch was für Peter (JAC)?!
- pps
- Beiträge: 574
- Registriert: 18.06.2021 23:05
- Has thanked: 126 times
- Been thanked: 229 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Schau mal in den MADS examples Ordner. Dort findest Du fast draw.
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
http://www.atarimania.com/mags/pdf/Atar ... -11-12.pdf
Seite 39 dürftest Du in Assembler fündig werden...
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Leider habe ich in meinen Mads-Ordnern kein fast-draw gefunden ....
- pps
- Beiträge: 574
- Registriert: 18.06.2021 23:05
- Has thanked: 126 times
- Been thanked: 229 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Das ist etwas versteckt. Habe mal kurz im github geschaut. Ich weiß, dass auch noch mehr Beispiele drin waren. Hier aber eines:
line.asm im examples Ordner
line.asm im examples Ordner
- pps
- Beiträge: 574
- Registriert: 18.06.2021 23:05
- Has thanked: 126 times
- Been thanked: 229 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Das ist nicht eigenständig, sondern gehört zur graphics library.
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... nun habe ich einige Vorlagen selber gesammelt und dank eurer Links auch Vorlagen und Alternativen gefunden ... alles toll und zum Teil sehr "fertig" aber auch komplex. Ich möchte aber eine ganz eigene Routine hier mit euch entwickeln, die möglichst schnell ist - am Ende wird sich zeigen, ob sie schnell und effektiv ist.
Wir wollen ja eine Gerade zeichnen und brauchen eigentlich die Steigung dafür. Die Steigung lässt sich einfach mathematisch bestimmen aus dem Quotienten der Differenzen der y- und x-Werte:
m = (y2-y1)/(x2-x1) = dy / dx
Am Ende vermeidet der Bresenham-Algorithmus dieses Teilen, da er prinzipiell zeitintensiv und schwierig ist.... ist das denn wirklich auch so.
Ich muss ja zum zeichnen der Gerade nur einmal teilen - am Anfang - und danach setze ich nur noch die Pixel in Abhängigkeit der Steigung m.
Wenn die Steigung m beispielsweise 3 beträgt, dann muss ich nach jeden Schritt nach vorne 3 Schritte hoch gehen usw.
Also muss zunächst eine schnelle Routine her fürs relativ einfache teilen:
Danach steht im Register x die Steigung. Die Routine braucht 5 Zyklen plus x (Anzahl der Durchgänge) mal 8 Zyklen.
2 Sonderfälle sortieren wir gleich am Anfang aus: Die vertikale und die horizontale Linie. Die zeichnen wir direkt.
Alles andere wird mittels der Steigung m gezeichnet.
Wir wollen ja eine Gerade zeichnen und brauchen eigentlich die Steigung dafür. Die Steigung lässt sich einfach mathematisch bestimmen aus dem Quotienten der Differenzen der y- und x-Werte:
m = (y2-y1)/(x2-x1) = dy / dx
Am Ende vermeidet der Bresenham-Algorithmus dieses Teilen, da er prinzipiell zeitintensiv und schwierig ist.... ist das denn wirklich auch so.
Ich muss ja zum zeichnen der Gerade nur einmal teilen - am Anfang - und danach setze ich nur noch die Pixel in Abhängigkeit der Steigung m.
Wenn die Steigung m beispielsweise 3 beträgt, dann muss ich nach jeden Schritt nach vorne 3 Schritte hoch gehen usw.
Also muss zunächst eine schnelle Routine her fürs relativ einfache teilen:
Code: Alles auswählen
SEC
LDA dy
loop SBC dx
INX
BCS loop
2 Sonderfälle sortieren wir gleich am Anfang aus: Die vertikale und die horizontale Linie. Die zeichnen wir direkt.
Alles andere wird mittels der Steigung m gezeichnet.
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Wenn die Steigung z.B. 2.5 ist, bekommst Du für die "Unterschlagung" der Nachkommastellen mit Deiner Assemblerroutine "lustige" Ergebnisse...Dr. Irata hat geschrieben: ↑22.05.2023 20:38Ich muss ja zum zeichnen der Gerade nur einmal teilen - am Anfang - und danach setze ich nur noch die Pixel in Abhängigkeit der Steigung m.
Wenn die Steigung m beispielsweise 3 beträgt, dann muss ich nach jeden Schritt nach vorne 3 Schritte hoch gehen usw.
Ich bin gespannt...
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... das ist wahr... bin auch mal gespannt. Den Fehler muss man evt. ausbügeln. Das Verfahren ist ja auch nur eine Art Näherung.
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Der Fehler muss in den Algorithmus einfließen.
Mit einem Algorithmus à la "nach zwei Pixel hoch, einen nach rechts" bekommst Du nicht immer eine Verbindung zwischen zwei Punkten: Du kannst Dir eine Menge Zeit und Aufwand sparen (und hast dabei noch den schnellsten Algorithmus), wenn Du Bresenham anwendest...
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
hmmmm.... warum das Rad neu erfinden, wenn es nicht sicher ist, ob es runder und besser ist, als das bereits bestehende...
Der Bresenham-Algorithmus ist ja speziell damals für die Linienzeichnung entwickelt worden.
Die Theorie ist dabei mathematisch relativ logisch und die Umsetzung einfach. Als Beispiel hier die Umsetzung in Basic:
... das kann man gut in Assembler konvertieren!
Der Bresenham-Algorithmus ist ja speziell damals für die Linienzeichnung entwickelt worden.
Die Theorie ist dabei mathematisch relativ logisch und die Umsetzung einfach. Als Beispiel hier die Umsetzung in Basic:
Code: Alles auswählen
REM Bresenham-Algorithmus für eine Linie im ersten Oktanten in Pseudo-Basic
dx = xend-xstart
dy = yend-ystart
REM im ersten Oktanten muss 0 < dy <= dx sein
REM Initialisierungen
x = xstart
y = ystart
SETPIXEL x,y
fehler = dx/2
REM Pixelschleife: immer ein Schritt in schnelle Richtung, hin und wieder auch einer in langsame
WHILE x < xend
REM Schritt in schnelle Richtung
x = x + 1
fehler = fehler - dy
IF fehler < 0 THEN
REM Schritt in langsame Richtung
y = y + 1
fehler = fehler + dx
END IF
SETPIXEL x,y
WEND
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... nun habe ich es doch mal mit meiner Methode probiert - zunächst - und es klappt damit auch ganz gut.
Die größte Schwierigkeit dabei war es eigentlich die Dinge mit einer vernünftigen Geschwindigkeit auch für später auf den Bildschirm zu bringen.
Ich habe ja eine Auflösung von (40*4) * 96 und muss in horizontaler Richtung mit 4 Phasen incl. EOR Befehlen arbeiten, in vertikaler Richtung habe ich eine sehr lange Tabelle, damit ich nicht ständig den y-Displaywert berechnen muss.
Und dann muss man ja auch noch 4 Fälle unterscheiden (dieser Ansatz macht nur eine Fall) - nämlich wenn die Steigung Minus und kleiner Eins ist.
Eine kleine Gerade zeichnen auf Assembler... klingt sooo einfach und ist so schwierig!!!
Die größte Schwierigkeit dabei war es eigentlich die Dinge mit einer vernünftigen Geschwindigkeit auch für später auf den Bildschirm zu bringen.
Ich habe ja eine Auflösung von (40*4) * 96 und muss in horizontaler Richtung mit 4 Phasen incl. EOR Befehlen arbeiten, in vertikaler Richtung habe ich eine sehr lange Tabelle, damit ich nicht ständig den y-Displaywert berechnen muss.
Und dann muss man ja auch noch 4 Fälle unterscheiden (dieser Ansatz macht nur eine Fall) - nämlich wenn die Steigung Minus und kleiner Eins ist.
Eine kleine Gerade zeichnen auf Assembler... klingt sooo einfach und ist so schwierig!!!
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
jetzt habe ich mal für verschiedene Steigungen die Gerade mit Start- und Zielpunkt verglichen ... und oh Wunder, wie schon vermutet runde ich ja den "Fehler" einfach weg und das macht sich natürlich bemerkbar... die Gerade erreicht den Endpunkt meistens nicht ...
Also wird nun der Algorithmus eingepflegt
Also wird nun der Algorithmus eingepflegt
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Nun habe ich den Algorithmus endlich korrekt umsetzen können.
Ich habe also den einfachen Bresenham-Algorithmus genommen - dabei muss man beachten, daß er so nur für einen Quadranten gilt mit positiver Steigung... alle anderen Fälle lassen sich dann aber entsprechend ableiten.
Ich habe das ganze für Antic D konzipiert, also wie oben beschrieben mit entsprechender Displaylist.
Die Bewegung in y-Achse läuft über 2 lange Tabellen und in x-Achse mit Berücksichtigung der 4-Bit-Phasenverschiebung.
Alles deutlich komplizierter als gedacht....
Meinen ersten Ansatz musste ich verwerfen, da zu ungenau.
Der Bresenham-Algorithmus funktionierte bei mir nicht so wie gedacht, da fehlte noch ein x 4 bei dx ... keine Ahnung warum. Habe ich da irgendwo unbewusst ein /4 eingebaut?? 4x dx muss man vermeiden, da man bei hohen dx über die 255 Grenze kommt, also addiert man zum Fehler einfach 4x dx !!
Jedenfalls so geht es jetzt ganz wunderbar!!
Hier der Code vom Algorithmus, wer Interesse am Gesamtcode hat einfach melden... wäre das ein Extrabeitrag fürs Magazin??
Ich habe also den einfachen Bresenham-Algorithmus genommen - dabei muss man beachten, daß er so nur für einen Quadranten gilt mit positiver Steigung... alle anderen Fälle lassen sich dann aber entsprechend ableiten.
Ich habe das ganze für Antic D konzipiert, also wie oben beschrieben mit entsprechender Displaylist.
Die Bewegung in y-Achse läuft über 2 lange Tabellen und in x-Achse mit Berücksichtigung der 4-Bit-Phasenverschiebung.
Alles deutlich komplizierter als gedacht....
Meinen ersten Ansatz musste ich verwerfen, da zu ungenau.
Der Bresenham-Algorithmus funktionierte bei mir nicht so wie gedacht, da fehlte noch ein x 4 bei dx ... keine Ahnung warum. Habe ich da irgendwo unbewusst ein /4 eingebaut?? 4x dx muss man vermeiden, da man bei hohen dx über die 255 Grenze kommt, also addiert man zum Fehler einfach 4x dx !!
Jedenfalls so geht es jetzt ganz wunderbar!!
Hier der Code vom Algorithmus, wer Interesse am Gesamtcode hat einfach melden... wäre das ein Extrabeitrag fürs Magazin??
Code: Alles auswählen
;------ Bresenham-Algorithmus ----
mva dx fehler
lsr fehler ; laut Bresenham wird der Fehler halbiert
@
#if .byte y1<y2 ; y1 = x und y2 = xend
;-------- x=x+1-----
ldy y1 ; mein x
jsr xrichtung ; Phasenverschiebung increment horizontal x+1
;-------------------
sec
lda fehler
sbc dy
sta fehler
#if .byte fehler>#128 ; =<0
;--------- y=y+1-----
inx ; mit x lade ich hier die Displaywerte aus einer Tabelle
inx ; für die Bewegung in vertikaler Richtung, 2x inx wegen
mwa convx,x jump ; jeweils 2 Bytes auslesen - das geht dann als selbstmod.
; Code bei jump1 rein --> jsr 0 springt dann jeweils an:
; xx0 lda 256*156,y
; eor phase
; sta 256*156,y
; rts
;--------------------
clc
lda fehler
adc dx ; hier muss man 4x dx zum Fehler wieder addieren
adc dx ; also quasi fehler + 4 x dx (geht aber nicht für hohe dx - also 4 x addieren)
adc dx
adc dx
sta fehler
#end
;---------- Print Punkt ------
jsr jump1
;-----------------------------
jmp @-
#end
jmp * ; Programm stoppt hier
jump1 jump = *+1
jsr 0
rts
;-------------- Ende -----------------------------
.proc xrichtung
#if .byte horiz=#3
mva #2 phase
mva #0 horiz
inc y1
rts
#end
#if .byte horiz=#2
mva #8 phase
inc horiz
rts
#end
#if .byte horiz=#1
mva #32 phase
inc horiz
rts
#end
#if .byte horiz=#0
mva #128 phase
inc horiz
rts
#end
rts
.endp
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... jetzt plötzlich - wie logisch - ist mir gerade klar geworden, warum ich den Faktor 4 für dx brauche, damit es stimmt....
meine Auflösung in x-Richtung ist ja theoretisch 160, aber da ich 4bit * 40 = 160 habe, rechne ich ja die ganze Zeit in x-Richtung mit 1/4... das macht natürlich den Algorithmus falsch - bzw. man muss das mit Faktor 4 korrigieren !!
Nun kann ich die anderen Fälle programmieren, damit kann man die Gerade in alle Richtungen zeichnen. Im Anschluss mache ich eine kleine animierte Demo...
meine Auflösung in x-Richtung ist ja theoretisch 160, aber da ich 4bit * 40 = 160 habe, rechne ich ja die ganze Zeit in x-Richtung mit 1/4... das macht natürlich den Algorithmus falsch - bzw. man muss das mit Faktor 4 korrigieren !!
Nun kann ich die anderen Fälle programmieren, damit kann man die Gerade in alle Richtungen zeichnen. Im Anschluss mache ich eine kleine animierte Demo...
- cas
- Beiträge: 861
- Registriert: 18.06.2021 21:01
- Wohnort: Solar System
- Has thanked: 196 times
- Been thanked: 399 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Ich habe in meinem PDF Archiv noch Artikel zu diesem Thema gefunden (siehe Anhänge).
- Dateianhänge
-
- 1985-06-01 Monitor 008.pdf
- (879.76 KiB) 29-mal heruntergeladen
-
- 2023-01-29 SunshineBooks_Machine_code_graphics_and_sound_for_the_Commodore_64.pdf
- (8.45 MiB) 24-mal heruntergeladen
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Es werden weniger Fälle, wenn Start- und Endpunkt vorher getauscht werden, falls sie "ungünstig" liegen....
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Noch ein Tipp: Beim 6502 ist es schneller man adressiert 16bit über 2 Tabellen (Hi- und Low-Byte getrennt).
Mal ein Auszug aus meiner Grafik-Lib:
Mal ein Auszug aus meiner Grafik-Lib:
Code: Alles auswählen
; Calculates and returns actual adress of line respective to screen base address,
; row offset value and given y/line number
; BYTE* __fastcall__
; Screen_GetRowAddress(BYTE nRow_);
.export _Screen_GetRowAddress
.proc _Screen_GetRowAddress
tay ; line to table index
lda _ScreenRowAdrTableL, Y ; access table (low)
ldx _ScreenRowAdrTableH, Y ; access table (high)
rts
.endproc
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
vielen vielen Dank für die inspirierende Ideen... schon cool, was alles möglich ist mit dem kleinen A8...
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... also ich habe meine Tabelle / Tabellen folgendermaßen angelegt:
Wenn eine Bewegung vertikal erfolgt, lade ich per selbstmodifizierenden Code eine entsprechende 16 Bit Adresse (die ist und bleibt fix und steht daher am Beginn des Programmes) in den JSR-Befehl, per JSR springe ich dann jeweils zu der kleinen und kurzen Routine, die den Plot in der jeweiligen Zeile macht.
Jegliche Rechnerei wird dadurch vermieden... ob das jetzt besonders schnell und gut ist, weiß ich nicht - besser als dauernd berechnen sicherlich.
Wenn eine Bewegung vertikal erfolgt, lade ich per selbstmodifizierenden Code eine entsprechende 16 Bit Adresse (die ist und bleibt fix und steht daher am Beginn des Programmes) in den JSR-Befehl, per JSR springe ich dann jeweils zu der kleinen und kurzen Routine, die den Plot in der jeweiligen Zeile macht.
Jegliche Rechnerei wird dadurch vermieden... ob das jetzt besonders schnell und gut ist, weiß ich nicht - besser als dauernd berechnen sicherlich.
Code: Alles auswählen
...
mwa convx,x jump ; dies ist der selbstmodifizierende Part
...
...
jump1 jump = *+1 ; aus der Tabelle conv erhält jump die Sprungadresse, durch *+1 wird die adresse hinter jsr gelegt
jsr 0
rts
....
;Tabelle der einzelnen Adressen - für jede Zeile eine:
convx .word $2200,$220a,$2214,$221e,$2228,$2232,$223c,$2246
.word $2250,$225a,$2264,$226e,$2278,$2282,$228c,$2296
.word $22a0,$22aa,$22b4,$22be,$22c8,$22d2,$22dc,$22e6
.word $22f0,$22fa,$2304,$230e,$2318,$2322,$232c,$2336
.word $2340,$234a,$2354,$235e,$2368,$2372,$237c,$2386
.word $2390,$239a,$23a4,$23ae,$23b8,$23c2,$23cc,$23d6
.word $23e0,$23ea,$23f4,$23fe,$2408,$2412,$241c,$2426
.word $2430,$243a,$2444,$244e,$2458,$2462,$246c,$2476
.word $2480,$248a,$2494,$249e,$24a8,$24b2,$24bc,$24c6
.word $24d0,$24da,$24e4,$24ee,$24f8,$2502,$250c,$2516
.word $2520,$252a,$2534,$253e,$2548,$2552,$255c,$2566
.word $2570,$257a,$2584,$258e,$2598,$25a2,$25ac,$25b6
; ein Ausschnitt der Plotroutinen. Diese beginnt zwingend bei $2200
xx0 lda 256*156,y
eor phase
sta 256*156,y
rts
xx1 lda 256*156+50,y
eor phase
sta 256*156+50,y
rts
xx2 lda 256*156+100,y
eor phase
sta 256*156+100,y
rts
xx3 lda 256*156+150,y
eor phase
sta 256*156+150,y
rts
xx4 lda 256*156+200,y
eor phase
sta 256*156+200,y
rts
.......
xx95 lda 256*175,y
eor phase
sta 256*175,y
rts
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
bedeutet das, wenn ich zum Beispiel statt mwa convx,x jump zunächst mva conv1 jump1 für low Byte und dann mva conv2 jump2 für high Byte selbstmodifiziedend aus 2 Tabellen hole und hinter jsr 0 platziere - ist das schneller???Irgendwer hat geschrieben: ↑24.05.2023 20:03Noch ein Tipp: Beim 6502 ist es schneller man adressiert 16bit über 2 Tabellen (Hi- und Low-Byte getrennt).
Mal ein Auszug aus meiner Grafik-Lib:Code: Alles auswählen
; Calculates and returns actual adress of line respective to screen base address, ; row offset value and given y/line number ; BYTE* __fastcall__ ; Screen_GetRowAddress(BYTE nRow_); .export _Screen_GetRowAddress .proc _Screen_GetRowAddress tay ; line to table index lda _ScreenRowAdrTableL, Y ; access table (low) ldx _ScreenRowAdrTableH, Y ; access table (high) rts .endproc
- cas
- Beiträge: 861
- Registriert: 18.06.2021 21:01
- Wohnort: Solar System
- Has thanked: 196 times
- Been thanked: 399 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Und noch zwei Artikel gefunden:
- Dateianhänge
-
- 1993-07-01 64er_199307_HQ.pdf
- (4.08 MiB) 26-mal heruntergeladen
-
- 1991-06-01 64er_199106_HQ.pdf
- (3.31 MiB) 23-mal heruntergeladen
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Halleluja, so wie Du das gemacht hast, wäre mir gar nicht eingefallen.
Mit haben schon die z.B. 192*2 Bytes (Antic F) für die Zeilenadresstabelle weh getan, aber für jede Zeile noch mal 9 Bytes für die Plot-Routine ist schon beachtlich - auch deswegen, weil Du für typische Anwendungsfälle nicht mit EOR auskommst, sondern AND zum Löschen und OR zum "Zeichnen" brauchst (was den Code nochmal aufbläht).
Ich benutze nicht MADS und tue mich mit den "mwa/mva"-Macros immer schwer. Aber optimal scheint mir das Vorgehen nicht zu sein.
(Ich verstehe auch nicht ganz Deinen +50, +100, +150 Offset (falls Du nicht eine spezielle Display-List hast, sollten Deine Zeilen 40 Bytes breit sein...?))
Ganz klassisch würde das EOR-Plotten ungefähr so aussehen:
Code: Alles auswählen
; Routine zum Plotten, X = x-Koordinate; Y = Y-Koordinate, zpPtr = 16-Bit Wort in der Zero-Page
Plot:
lda _ScreenRowAdrTableL, Y ; access table (low)
sta zpPtr
lda _ScreenRowAdrTableH, Y ; access table (high)
sta zpPtr+1
txa ;
lsr a ; / 2
lsr a ; / 4 ( 4 Pixel / Byte )
tay ; = zeilen offset
; hier könnte code stehen der 'phase' (aus Deinem Code) errechnet
; aus der X-coordinate 2 bits nimmt für eine Maske aus einer Tabelle
; txa
; and #3
; tax
; lda PixelMask, x ; farbabhängig
; sta phase
lda (zpPtr), Y
eor phase
sta (zpPtr), Y
rts
PixelMask:
.byte %00000011
.byte %00001100
.byte %00110000
.byte %11000000
Noch ein Tipp:
Statt
Code: Alles auswählen
jsr irgendwohin
rts
Code: Alles auswählen
jmp irgendwohin
Und noch ein Hinweis: Die Literatur, die 'cas' hier verlinkt hat ist sicherlich interessant, aber wenn sie für den C64 ist sehr mit Vorsicht zu genießen. Der C64 hat ein ganz anderen Bildschirmspeicheraufbau, was die Sache noch komplizierter macht...
Weiterhin viel Spaß beim Entdecken!
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... tatsächlich hatte ich aus älteren Überlegungen (Feinscrol/Grobscrol) die Displaylist ganz anders aufgebaut. Für horizontales Feinscrolling braucht man ja eine Breite von 48 statt 40 (ich habe gleich 50 genommen, weil es mir übersichtlicher erschien) - jede Zeil der Displaylist hat entsprechend einen eigenen Sprungbefehl mit entsprechender Adresse wegen des dann auch zu erwartenden Grobscroll mit Displaylistmanipulation. Da ich aber keinen Feinscroll brauche bei dem Programm, macht es Sinn, die Displaylist wieder ganz normal zu strukturieren.
Die Plotroutine sieht gut aus - ich werde das umbauen. Danke für alle Hinweise...
Die Plotroutine sieht gut aus - ich werde das umbauen. Danke für alle Hinweise...
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... mit welcher Umgebung programmierst du denn??Irgendwer hat geschrieben: ↑25.05.2023 01:40Halleluja, so wie Du das gemacht hast, wäre mir gar nicht eingefallen.
Mit haben schon die z.B. 192*2 Bytes (Antic F) für die Zeilenadresstabelle weh getan, aber für jede Zeile noch mal 9 Bytes für die Plot-Routine ist schon beachtlich - auch deswegen, weil Du für typische Anwendungsfälle nicht mit EOR auskommst, sondern AND zum Löschen und OR zum "Zeichnen" brauchst (was den Code nochmal aufbläht).
Ich benutze nicht MADS und tue mich mit den "mwa/mva"-Macros immer schwer. Aber optimal scheint mir das Vorgehen nicht zu sein.
(Ich verstehe auch nicht ganz Deinen +50, +100, +150 Offset (falls Du nicht eine spezielle Display-List hast, sollten Deine Zeilen 40 Bytes breit sein...?))
Ganz klassisch würde das EOR-Plotten ungefähr so aussehen:
Es gibt noch genug zum Austoben: Der Trick bei einer Linienroutine ist nicht einzelne Pixel zu plotten, sondern das Wissen, dass sie benachbart sind code-technisch elegant auszunutzen... (z.B. selbe Zeile, selbes Byte etc.)Code: Alles auswählen
; Routine zum Plotten, X = x-Koordinate; Y = Y-Koordinate, zpPtr = 16-Bit Wort in der Zero-Page Plot: lda _ScreenRowAdrTableL, Y ; access table (low) sta zpPtr lda _ScreenRowAdrTableH, Y ; access table (high) sta zpPtr+1 txa ; lsr a ; / 2 lsr a ; / 4 ( 4 Pixel / Byte ) tay ; = zeilen offset ; hier könnte code stehen der 'phase' (aus Deinem Code) errechnet ; aus der X-coordinate 2 bits nimmt für eine Maske aus einer Tabelle ; txa ; and #3 ; tax ; lda PixelMask, x ; farbabhängig ; sta phase lda (zpPtr), Y eor phase sta (zpPtr), Y rts PixelMask: .byte %00000011 .byte %00001100 .byte %00110000 .byte %11000000
Noch ein Tipp:
Stattkann man auchCode: Alles auswählen
jsr irgendwohin rts
schreiben und spart Zeit und ein Byte...Code: Alles auswählen
jmp irgendwohin
Und noch ein Hinweis: Die Literatur, die 'cas' hier verlinkt hat ist sicherlich interessant, aber wenn sie für den C64 ist sehr mit Vorsicht zu genießen. Der C64 hat ein ganz anderen Bildschirmspeicheraufbau, was die Sache noch komplizierter macht...
Weiterhin viel Spaß beim Entdecken!
- LarsImNetz
- Beiträge: 170
- Registriert: 24.08.2021 18:27
- Has thanked: 127 times
- Been thanked: 89 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Eine Info zum C64 und dessen HiRes Grafik.
* Beim AtariXL ist die Grafik wirklich Zeilenweise angeordnet. Also das das nächste Byte (+1) liegt in der selben Zeile nur halt ein paar Pixel weiter rechts.
Ein Index sieht so aus...
0, 1, 2, 3, ... 39,
40,41,42...
...
* Beim C64 ist die Anordnung eher wie beim Zeichensatz. 8 Bytes untereinander, dann kommen die nächsten 8 Bytes untereinander...
Ein Index beim C64 sieht so aus...
0,8,16,24, ... 312,
1,9,17,
2,10,18,
3,11,19,
...
7,15,23,...
320,328,...
321,...
...
Das sollte man berücksichtigen, wenn man sich C64-Linienalgorithmen ansieht und versucht diese zu verstehen.
LG
Lars
- LarsImNetz
- Beiträge: 170
- Registriert: 24.08.2021 18:27
- Has thanked: 127 times
- Been thanked: 89 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Ich bin auch kein Fan von MADS und mva/mwa. Das wird sich erst ändern, wenn es den Assembler native auf Linux gibt. BTW: Wine ist nicht Linux.
- cas
- Beiträge: 861
- Registriert: 18.06.2021 21:01
- Wohnort: Solar System
- Has thanked: 196 times
- Been thanked: 399 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
Hallo Lars,LarsImNetz hat geschrieben: ↑25.05.2023 16:20Ich bin auch kein Fan von MADS und mva/mwa. Das wird sich erst ändern, wenn es den Assembler native auf Linux gibt. BTW: Wine ist nicht Linux.
warum "wenn", den gibt es doch schon lange (eigendlich seit immer) "nativ" unter Linux:
Code: Alles auswählen
apt install fpc
git clone https://github.com/tebe6502/Mad-Assembler
cd Mad-Assembler
fpc -Mdelphi -vh -O3 mads.pas
sudo cp mads /usr/local/bin
- LarsImNetz
- Beiträge: 170
- Registriert: 24.08.2021 18:27
- Has thanked: 127 times
- Been thanked: 89 times
- Kontaktdaten:
- LarsImNetz
- Beiträge: 170
- Registriert: 24.08.2021 18:27
- Has thanked: 127 times
- Been thanked: 89 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
So, hier mal eine etwas schnellere Line-Zeichen-Routine.
Es gab mal irgendwo einen Source mit 8 Versionen, das hier ist die letzte davon.
Die Routine schafft locker 300 Linien pro Sekunde. (rand(160), rand(192),rand(160), rand(192)) ist leider etwas ungenau, dafür verdammt flott.
Die Parameterübergabe ist für meinen Compiler, ähnlich wie beim cc65. Per (heap_ptr),y realisiert. Wenn man sich die komplizierte, teure Parameterübergabe spart, ist diese Routine noch schneller. Der Code ist kompatibel zum Atasm Assembler. Der Code zeichnet 4 Pixel gleichzeitig, mehr hab ich bisher auch nicht verstanden.
Wirklich das schnellste, was ich bisher gesehen habe. Ich habe auch den Code von ERU, zum Vergleich, die schafft ca. 216 Linien pro Sekunde, nur um mal ein paar Zahlen zu nennen. Mit einfachem Bresenham komme ich in meinem Compiler nicht über 80 Linien pro Sekunde, was aber am expliziten PLOT(x,y) liegt.
Wer die Routine nutzen möchte, sollte die @MULT40_low und _high Tabelle noch setzen, hab ich hier nicht mit angegeben.
LG
Lars
Es gab mal irgendwo einen Source mit 8 Versionen, das hier ist die letzte davon.
Die Routine schafft locker 300 Linien pro Sekunde. (rand(160), rand(192),rand(160), rand(192)) ist leider etwas ungenau, dafür verdammt flott.
Die Parameterübergabe ist für meinen Compiler, ähnlich wie beim cc65. Per (heap_ptr),y realisiert. Wenn man sich die komplizierte, teure Parameterübergabe spart, ist diese Routine noch schneller. Der Code ist kompatibel zum Atasm Assembler. Der Code zeichnet 4 Pixel gleichzeitig, mehr hab ich bisher auch nicht verstanden.
Wirklich das schnellste, was ich bisher gesehen habe. Ich habe auch den Code von ERU, zum Vergleich, die schafft ca. 216 Linien pro Sekunde, nur um mal ein paar Zahlen zu nennen. Mit einfachem Bresenham komme ich in meinem Compiler nicht über 80 Linien pro Sekunde, was aber am expliziten PLOT(x,y) liegt.
Wer die Routine nutzen möchte, sollte die @MULT40_low und _high Tabelle noch setzen, hab ich hier nicht mit angegeben.
LG
Lars
Code: Alles auswählen
.LOCAL
; TODO
; Dieser LINE Algorithmus funktioniert nur
; in graphics 7 und 15 (40 Bytes breit)
; bis 160 x 192!!! Weil nur 8 Bit breit
; ist dafuer sehr schnell, leider ungenau => eher unbrauchbar
; BITMSK = $6E
; SHFAMT = $6F
;ROWCRS = $54
;COLCRS = $55
;OLDROW = $5A
;OLDCOL = $5B
;ROWAC = $70
;ROWADC = $72
;CFLAG = $74
;RFLAG = $75
;DELTAROW= $76
;DELTACOL= $77
;ATACHR = $02FB
;opcodes for self-modifying code
?_OC_BIT_0P_ = $24
?_OC_DEC_0P_ = $C6 ;11000110
?_OC_INC_0P_ = $E6 ;11100110 ;XOR 32 ;$20
?_OC_DEX_ = $CA ;11001010
?_OC_INX_ = $E8 ;11101000 ;XOR 34 ;$22
?_OC_AND_AX_ = $3D
?_OC_EOR_AX_ = $5D
?_OC_ORA_AX_ = $1D
; @REG ist bei mir ab Adresse 220 (Floating-Point-Register)
?L0 = @REG+0 ; $B0
?L1 = @REG+1 ; $B1
?L2 = @REG+2 ; $B2
?L3 = @REG+3 ; $B3
?L4 = @REG+4 ; $B4
?L5 = @REG+5 ; $B5
?L6 = @REG+6 ; $B6
?L7 = @REG+7 ; $B7
?m0 = @REG+8
?m1 = @REG+9
?m2 = @REG+10
?x0 = @REG+11
?x1 = @REG+12
?x2 = @REG+13
@SETLINECOLOR
@SETLINECOLOR_i
LDY #1 ; color 0 - 3
LDA (@HEAP_PTR),Y ; wert holen
and #3
TAX
LDY ?MASTSET,X
STY ?SET1IMASKT
STY ?SET1IMASKW
STY ?SET2IMASKT
STY ?SET2IMASKW
STY ?SET3IMASKT
STY ?SET3IMASKW
STY ?SET4IMASKT
STY ?SET4IMASKW
LDA ADRCOLMHI,X
STA ?GET1CMASKHT
STA ?GET1CMASKHW
STA ?GET2CMASKHT
STA ?GET2CMASKHW
STA ?GET3CMASKHT
STA ?GET3CMASKHW
STA ?GET4CMASKHT
STA ?GET4CMASKHW
RTS
; DRAWLINE ;v6
; LDA #1
; STA OLDROW
; LDA #153
; STA OLDCOL
; LDA #072
; STA ROWCRS
; LDA #1
; STA COLCRS
@LINE
@LINE_IIII
@FASTLINE2BIT
@FASTLINE2BIT_IIII
LDY #1 ; XSTART
LDA (@HEAP_PTR),Y ; wert holen
STA OLDCOL ; ?XSTART
LDY #3 ; YSTART
LDA (@HEAP_PTR),Y ; wert holen
STA OLDROW ; ?YSTART
LDY #5 ; XEND
LDA (@HEAP_PTR),Y ; wert holen
STA COLCRS ; ?XEND
LDY #7 ; YEND
LDA (@HEAP_PTR),Y ; wert holen
STA ROWCRS ; ?YEND
LDA OLDROW
SEC
SBC ROWCRS
BCS ?OLDROWFIRST
LDX OLDCOL ;3
LDY COLCRS ;3
STY OLDCOL ;3
STX COLCRS ;3
LDY OLDROW
SBC #0
EOR #255
JMP ?STOREROWDELTA
?OLDROWFIRST
LDY ROWCRS
?STOREROWDELTA
STA ?aw_WIDE_DELTA_RI
STA ?aw_TALL_DELTA_RI
LSR A
LSR A
STA ?X1
BNE ?NOVS2
BCC ?NOVS2
LDA #01
?NOVS2
STA ?m2
LDA @MULT40_LOW,Y
STA ?L0
LDA @MULT40_HIGH,Y
STA ?L1
TYA
CLC
ADC ?X1
TAY
LDA @MULT40_LOW,Y
STA ?L2
LDA @MULT40_HIGH,Y
STA ?L3
TYA
CLC
ADC ?m2
TAY
LDA @MULT40_LOW,Y
STA ?L4
LDA @MULT40_HIGH,Y
STA ?L5
TYA
CLC
ADC ?X1
TAY
LDA @MULT40_LOW,Y
STA ?L6
LDA @MULT40_HIGH,Y
STA ?L7
LDA OLDCOL
SEC
SBC COLCRS
BCS ?aw_HOZ_POS
?aw_HOZ_NEG
SBC #0
EOR #255
TAY
LSR A
LSR A
STA ?m1
STA ?x0
STA ?X2
BNE ?noHS1
BCC ?noHS1
LDA #1
?noHS1
STA ?m2
LDA COLCRS
SEC
SBC ?X2
STA ?GET1CMASKLW
STA ?GET1TABLW
STA ?GET1CMASKLT
STA ?GET1TABLT
SBC ?m2
STA ?GET2CMASKLW
STA ?GET2TABLW
STA ?GET2CMASKLT
STA ?GET2TABLT
SBC ?X2
STA ?GET3CMASKLW
STA ?GET3TABLW
STA ?GET3CMASKLT
STA ?GET3TABLT
SBC ?X2
STA ?GET4CMASKLW
STA ?GET4TABLW
STA ?GET4CMASKLT
STA ?GET4TABLT
LDX #?_OC_DEX_
JMP ?compARE_SLOPE
?aw_HOZ_POS
TAY
LSR A
LSR A
STA ?X2
BNE ?noHS2
BCC ?noHS2
LDA #01
?noHS2
STA ?m2
LDA COLCRS
STA ?GET1CMASKLW
STA ?GET1TABLW
STA ?GET1CMASKLT
STA ?GET1TABLT
CLC
ADC ?X2
STA ?GET2CMASKLW
STA ?GET2TABLW
STA ?GET2CMASKLT
STA ?GET2TABLT
ADC ?m2
STA ?GET3CMASKLW
STA ?GET3TABLW
STA ?GET3CMASKLT
STA ?GET3TABLT
ADC ?X2
STA ?GET4CMASKLW
STA ?GET4TABLW
STA ?GET4CMASKLT
STA ?GET4TABLT
STA ?m0
LDX #0
STX ?x0
LDX #?_OC_INX_
?compARE_SLOPE
CPY ?aw_WIDE_DELTA_RI
BCC ?aw_TALLSLOPE
BEQ ?aw_TALLSLOPE
?aw_WIDESLOPE
STY ?aw_WIDE_DELTA_CI
TYA
SEC
SBC ?m2
STA ?m1
STX ?COLADC1
LDA ?X2
BEQ ?aw_WIDESLOPE0
SEC
LDX ?x0
?aw_WIDE_LOOP
?COLADC1
INX ;2
?GET1TABLW = *+1
LDY ?TAB4DIV,X ;6
LDA (?L0),Y ;11
?SET1IMASKW = *
?GET1CMASKLW = *+1
?GET1CMASKHW = *+2
ORA $FF00,X ;15
STA (?L0),Y ;20
?GET2TABLW = *+1
LDY ?TAB4DIV,X ;24
LDA (?L2),Y ;29
?SET2IMASKW = *
?GET2CMASKLW = *+1
?GET2CMASKHW = *+2
ORA $FF00,X ;33
STA (?L2),Y ;38
?GET3TABLW = *+1
LDY ?TAB4DIV,X ;42
LDA (?L4),Y ;47
?SET3IMASKW = *
?GET3CMASKLW = *+1
?GET3CMASKHW = *+2
ORA $FF00,X ;51
STA (?L4),Y ;56
?GET4TABLW = *+1
LDY ?TAB4DIV,X ;60
LDA (?L6),Y ;65
?SET4IMASKW = *
?GET4CMASKLW = *+1
?GET4CMASKHW = *+2
ORA $FF00,X ;69
STA (?L6),Y ;74
LDA ?m1 ;77 -3
?aw_WIDE_DELTA_RI=*+1
SBC #$FF ;79 -5
STA ?m1 ;82 -8
BCS ?aw_WIDE_SKIP ;85
?aw_WIDE_DELTA_CI=*+1
ADC #$FF
STA ?m1
LDA ?L0
CLC
ADC #40
STA ?L0
BCC ?no_WIDE_H1INC
INC ?L1
CLC
?no_WIDE_H1INC
LDA ?L2
ADC #40
STA ?L2
BCC ?no_WIDE_H2INC
INC ?L3
CLC
?no_WIDE_H2INC
LDA ?L4
ADC #40
STA ?L4
BCC ?no_WIDE_H3INC
INC ?L5
CLC
?no_WIDE_H3INC
LDA ?L6
ADC #40
STA ?L6
BCC ?no_WIDE_H4INC
INC ?L7
?no_WIDE_H4INC
SEC
?aw_WIDE_SKIP
?LAST_WIDE_X = *+1
DEC ?X2 ;88
BNE ?aw_WIDE_LOOP ;91
?aw_WIDESLOPE0
RTS
;
?aw_TALLSLOPE
STY ?aw_TALL_DELTA_CI
LDA ?aw_TALL_DELTA_RI
SEC
SBC ?m2
STA ?m1
DEC ?X1
BEQ ?aw_WIDESLOPE0
BMI ?aw_WIDESLOPE0
STX ?COLADC2
LDX ?x0
?aw_TALL_LOOP
?GET1TABLT = *+1
LDY ?TAB4DIV,X ;4
LDA (?L0),Y ;9
?SET1IMASKT = *
?GET1CMASKLT = *+1
?GET1CMASKHT = *+2
ORA $FF00,X ;14
STA (?L0),Y ;19
?GET2TABLT = *+1
LDY ?TAB4DIV,X ;23
LDA (?L2),Y ;28
?SET2IMASKT = *
?GET2CMASKLT = *+1
?GET2CMASKHT = *+2
ORA $FF00,X ;32
STA (?L2),Y ;37
?GET3TABLT = *+1
LDY ?TAB4DIV,X ;4
LDA (?L4),Y ;9
?SET3IMASKT = *
?GET3CMASKLT = *+1
?GET3CMASKHT = *+2
ORA $FF00,X ;14
STA (?L4),Y ;19
?GET4TABLT = *+1
LDY ?TAB4DIV,X ;23
LDA (?L6),Y ;28
?SET4IMASKT = *
?GET4CMASKLT = *+1
?GET4CMASKHT = *+2
ORA $FF00,X ;32
STA (?L6),Y ;37
LDA ?m1 ;40
SEC ;42
?aw_TALL_DELTA_CI=*+1
SBC #$FF ;44
BCS ?aw_TALL_SKIP ;47
?aw_TALL_DELTA_RI=*+1
ADC #$FF ;
?COLADC2
INX
?aw_TALL_SKIP
STA ?m1 ;50
LDA ?L0 ;53
CLC ;55
ADC #40 ;57
STA ?L0 ;60
BCC ?no_TALL_H1INC ;63
INC ?L1
CLC
?NO_TALL_H1INC
LDA ?L2 ;66
ADC #40 ;68
STA ?L2 ;71
BCC ?no_TALLH2DEC ;74
INC ?L3
?NO_TALLH2DEC
LDA ?L4 ;53
CLC ;55
ADC #40 ;57
STA ?L4 ;60
BCC ?no_TALL_H3INC ;63
INC ?L5
CLC
?NO_TALL_H3INC
LDA ?L6 ;66
ADC #40 ;68
STA ?L6 ;71
BCC ?NO_TALLH4DEC ;74
INC ?L7
?NO_TALLH4DEC
DEC ?X1 ;77
BPL ?AW_TALL_LOOP ;80
?DREND
RTS
* = (* +$FF) & $FF00
ANDMASK
.byte 63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252
.byte 63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252
.byte 63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252
.byte 63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252
.byte 63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252,63,207,243,252
ADRCOLMLO
.byte <ANDMASK, <COLORMASK1, <COLORMASK2, <COLORMASK3
ADRCOLMHI
.byte >ANDMASK, >COLORMASK1, >COLORMASK2, >COLORMASK3
?MASTSET
.byte ?_OC_AND_AX_, ?_OC_ORA_AX_, ?_OC_ORA_AX_, ?_OC_ORA_AX_
.byte ?_OC_AND_AX_, ?_OC_EOR_AX_, ?_OC_EOR_AX_, ?_OC_EOR_AX_
;M1DIMG
; .byte 3,12,48,192
;M2DIMG
; .byte 1,4,16,64
;EMPTYDATA
; .byte 0,0,0,0
; ORG LINEDATAPAGE + 256
* = (* +$FF) & $FF00
COLORMASK1
.byte 64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1
.byte 64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1
.byte 64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1
.byte 64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1
.byte 64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1,64,16,4,1
; ORG LINEDATAPAGE + 512
* = (* +$FF) & $FF00
COLORMASK2
.byte 128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2
.byte 128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2
.byte 128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2
.byte 128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2
.byte 128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2,128,32,8,2
; ORG LINEDATAPAGE + 768
* = (* +$FF) & $FF00
COLORMASK3
.byte 192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3
.byte 192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3
.byte 192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3
.byte 192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3
.byte 192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3,192,48,12,3
; ORG LINEDATAPAGE + 1024
* = (* +$FF) & $FF00
?TAB4DIV
.byte 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8,8,8,8,9,9,9,9
.byte 10,10,10,10,11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19
.byte 20,20,20,20,21,21,21,21,22,22,22,22,23,23,23,23,24,24,24,24,25,25,25,25,26,26,26,26,27,27,27,27,28,28,28,28,29,29,29,29
.byte 30,30,30,30,31,31,31,31,32,32,32,32,33,33,33,33,34,34,34,34,35,35,35,35,36,36,36,36,37,37,37,37,38,38,38,38,39,39,39,39
.align 256
; muessen initialisiert werden! Die zeigen auf den Graphics-Speicher, jeder Wert ist um 40 Bytes groesser
@MULT40_low
.dc 256 0
@MULT40_high
.dc 256 0
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... ich sehe schon, das Thema gibt eine Menge her.
Nach welchem mathematischen Prinzip arbeiten denn diese schnellen Lösungen?
Nach welchem mathematischen Prinzip arbeiten denn diese schnellen Lösungen?
- Irgendwer
- Beiträge: 77
- Registriert: 25.08.2021 19:05
- Has thanked: 16 times
- Been thanked: 34 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
cc65/ca65
eigentlich versuche ich inzwischen soviel wie geht in cc65 zu schreiben und erst wenn es zeitkritisch wird, entweder cc65 zu verbessern oder auf Assembler zu wechseln. Klappt bisher ganz gut.
Größte Hürde bei cc65 ist, wenn man es denn irgendwann kann, gleichzeitig die größte Hilfe: Die Linker-Configuration.
Gerade beim Atari mit seinen vielen Speicherausrichtungsanforderungen (Zeichensätze, PMG, DL, Bildschirmspeicher) ist das am Anfang kompliziert - inzwischen aber für die Atari-Compound-Dateien besser unterstützt und etwas einfacher.
(Die PixelMask-Tabelle oben ist glaube ich falsch herum, um 1:40 kann das schon einmal passieren... )
Grüße!
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
ich habe jetzt die gesamte Displaylist angepasst und auch die Plotroutine... was noch fehlt ist die schnellere Phasenverschiebung. Leider bin ich am WE unterwegs und kann da nicht weitermachen... zunächst. Das Projekt ist höchst spannend.
Ich habe eine Zählerroutine mit reingemacht, damit ich die Geschwindigkeit testen kann.... bislang schafft die Routine ca 90 lange Linien pro Sekunde in Pal.
Jetzt das noch weiter optimieren... ich möchte mindestens 150 / Sekunde zeichnen können, dann gehts weiter mit 3D
Ich habe eine Zählerroutine mit reingemacht, damit ich die Geschwindigkeit testen kann.... bislang schafft die Routine ca 90 lange Linien pro Sekunde in Pal.
Jetzt das noch weiter optimieren... ich möchte mindestens 150 / Sekunde zeichnen können, dann gehts weiter mit 3D
- Dr. Irata
- Beiträge: 963
- Registriert: 24.08.2021 14:40
- Has thanked: 119 times
- Been thanked: 285 times
- Kontaktdaten:
Re: Basic Plot / Drawto in Assembler
... ich habe gerade mal die alte Routine für die Phasenverschiebung komplett rausgenommen - die Gerade sieht natürlich jetzt falsch aus, aber die Geschwindigkeit nimmt damit dramatisch zu: Fast 500 Linien pro Sekunde zeichnet die Routine mit dem Bresenham-Algorithmus. Der Bremsklotz ist also die Unterroutine der Phasenverschiebung. Das ahnte ich schon, da ich die Routine ohne Optimierung gebaut habe. Hier gilt es jetzt anzusetzen und da habe ich auch schon einige Ideen. Eigentlich geht ja der Bresenham immer um einen X-Wert voran und ab und zu halt mal um einen Y-Wert nach oben oder unten.
Das schnellste wird wohl sein, ein wenig Speicher zu opfern und die Routine einfach 4x hintereinander laufen zu lassen - jeweils mit phasenverschobenen Wert der zu platten ist. Dann gibt es praktische keine relevante Verzögerung und ich hoffe damit auf 300-400 Linien pro Sekunde zu kommen - damit könnte man arbeiten.
Danach programmiere ich die ganzen Spezialfälle (positive Steigung, negative Steigung, jeweils Steigung >1 und <1, horizontale Linie, vertikale Linie, jeweils Steigung genau 1 / -1...... es werden also wohl 10 Fälle jeweils mit 4x Code wegen der Phasenverschiebung. Großer Aufwand - Maximale Geschwindigkeit....
Das schnellste wird wohl sein, ein wenig Speicher zu opfern und die Routine einfach 4x hintereinander laufen zu lassen - jeweils mit phasenverschobenen Wert der zu platten ist. Dann gibt es praktische keine relevante Verzögerung und ich hoffe damit auf 300-400 Linien pro Sekunde zu kommen - damit könnte man arbeiten.
Danach programmiere ich die ganzen Spezialfälle (positive Steigung, negative Steigung, jeweils Steigung >1 und <1, horizontale Linie, vertikale Linie, jeweils Steigung genau 1 / -1...... es werden also wohl 10 Fälle jeweils mit 4x Code wegen der Phasenverschiebung. Großer Aufwand - Maximale Geschwindigkeit....
Wer ist online?
Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste