Basic Plot / Drawto in Assembler

Moderator: Rockford

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

Ich stelle das Thema mal online zur Diskussion:

Eine Assemblerroutine maximal schnell und effektiv um ein Plot/Drawto in Antic D nachzubilden...

Ideen??

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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.

FlorianD
Beiträge: 182
Registriert: 19.08.2021 00:18
Has thanked: 21 times
Been thanked: 55 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von FlorianD »

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

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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)?!

Benutzeravatar
pps
Beiträge: 511
Registriert: 18.06.2021 23:05
Has thanked: 112 times
Been thanked: 204 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von pps »

Schau mal in den MADS examples Ordner. Dort findest Du fast draw.
PP´s of STARSOFTBerlin__________github|meine Webseite

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
22.05.2023 09:26
... vielen Dank. Sehr interessanter Artikel (wie immer bei Peter Finzel). Leider in Action! geschrieben.
http://www.atarimania.com/mags/pdf/Atar ... -11-12.pdf

Seite 39 dürftest Du in Assembler fündig werden...

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

Leider habe ich in meinen Mads-Ordnern kein fast-draw gefunden ....

Benutzeravatar
pps
Beiträge: 511
Registriert: 18.06.2021 23:05
Has thanked: 112 times
Been thanked: 204 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von pps »

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
Screenshot_20230522_104818.jpg
PP´s of STARSOFTBerlin__________github|meine Webseite

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

gefunden, läuft aber nicht....

Benutzeravatar
pps
Beiträge: 511
Registriert: 18.06.2021 23:05
Has thanked: 112 times
Been thanked: 204 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von pps »

Das ist nicht eigenständig, sondern gehört zur graphics library.
PP´s of STARSOFTBerlin__________github|meine Webseite

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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:

Code: Alles auswählen

		SEC
		LDA dy
loop		SBC dx
		INX
		BCS loop
		
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.

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
22.05.2023 20:38
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.
Wenn die Steigung z.B. 2.5 ist, bekommst Du für die "Unterschlagung" der Nachkommastellen mit Deiner Assemblerroutine "lustige" Ergebnisse...

Ich bin gespannt...

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... das ist wahr... bin auch mal gespannt. Den Fehler muss man evt. ausbügeln. Das Verfahren ist ja auch nur eine Art Näherung.

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
23.05.2023 10:26
Den Fehler muss man evt. ausbügeln. Das Verfahren ist ja auch nur eine Art Näherung.
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:
Unbenannt.png
Unbenannt.png (698 Bytes) 2653 mal betrachtet
Du kannst Dir eine Menge Zeit und Aufwand sparen (und hast dabei noch den schnellsten Algorithmus), wenn Du Bresenham anwendest...

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

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:

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
... das kann man gut in Assembler konvertieren!

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

18C4730C-ACAC-4634-BEB0-4DA41C32668E.jpeg
Dateianhänge
A52BBA5F-6916-4335-8982-B72C92E12872.jpeg
9B1F8F45-C21B-4EFC-A01D-67B54844775B.jpeg
C6B26459-0EA1-43BE-9B55-5833C6C9B948.jpeg

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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!!!

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

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 ;-)

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

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?? :D

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

Benutzeravatar
cas
Beiträge: 811
Registriert: 18.06.2021 21:01
Wohnort: Solar System
Has thanked: 180 times
Been thanked: 361 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von cas »

Dr. Irata hat geschrieben:
24.05.2023 13:33
wäre das ein Extrabeitrag fürs Magazin?? :D

Ja !!

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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...

Benutzeravatar
cas
Beiträge: 811
Registriert: 18.06.2021 21:01
Wohnort: Solar System
Has thanked: 180 times
Been thanked: 361 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von cas »

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) 20-mal heruntergeladen
2023-01-29 SunshineBooks_Machine_code_graphics_and_sound_for_the_Commodore_64.pdf
(8.45 MiB) 17-mal heruntergeladen

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
24.05.2023 19:29
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...
Es werden weniger Fälle, wenn Start- und Endpunkt vorher getauscht werden, falls sie "ungünstig" liegen....

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

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:

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

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

vielen vielen Dank für die inspirierende Ideen... schon cool, was alles möglich ist mit dem kleinen A8...

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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.

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


Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

Irgendwer hat geschrieben:
24.05.2023 20:03
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:

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
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???

Benutzeravatar
cas
Beiträge: 811
Registriert: 18.06.2021 21:01
Wohnort: Solar System
Has thanked: 180 times
Been thanked: 361 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von cas »

Und noch zwei Artikel gefunden:
Dateianhänge
1993-07-01 64er_199307_HQ.pdf
(4.08 MiB) 19-mal heruntergeladen
1991-06-01 64er_199106_HQ.pdf
(3.31 MiB) 16-mal heruntergeladen

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
24.05.2023 20:54
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???
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

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.)

Noch ein Tipp:
Statt

Code: Alles auswählen

			jsr irgendwohin
			rts
kann man auch

Code: Alles auswählen

			jmp irgendwohin
schreiben und spart Zeit und ein Byte...

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!

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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...

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

Irgendwer hat geschrieben:
25.05.2023 01:40
Dr. Irata hat geschrieben:
24.05.2023 20:54
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???
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

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.)

Noch ein Tipp:
Statt

Code: Alles auswählen

			jsr irgendwohin
			rts
kann man auch

Code: Alles auswählen

			jmp irgendwohin
schreiben und spart Zeit und ein Byte...

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!
... mit welcher Umgebung programmierst du denn??

Benutzeravatar
LarsImNetz
Beiträge: 149
Registriert: 24.08.2021 18:27
Has thanked: 105 times
Been thanked: 79 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von LarsImNetz »

cas hat geschrieben:
24.05.2023 21:05
Und noch zwei Artikel gefunden:
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

Benutzeravatar
LarsImNetz
Beiträge: 149
Registriert: 24.08.2021 18:27
Has thanked: 105 times
Been thanked: 79 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von LarsImNetz »

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.

Benutzeravatar
cas
Beiträge: 811
Registriert: 18.06.2021 21:01
Wohnort: Solar System
Has thanked: 180 times
Been thanked: 361 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von cas »

LarsImNetz hat geschrieben:
25.05.2023 16:20
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.
Hallo Lars,

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
Ich kann Dir gerne auch ein "mads" binary für i686/amd64/arm/aarch64/m68k kompilieren.

Benutzeravatar
LarsImNetz
Beiträge: 149
Registriert: 24.08.2021 18:27
Has thanked: 105 times
Been thanked: 79 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von LarsImNetz »

passt schon, hab ihn gerade selbst gebaut.

Benutzeravatar
LarsImNetz
Beiträge: 149
Registriert: 24.08.2021 18:27
Has thanked: 105 times
Been thanked: 79 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von LarsImNetz »

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

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
 	

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... ich sehe schon, das Thema gibt eine Menge her.
Nach welchem mathematischen Prinzip arbeiten denn diese schnellen Lösungen?

Benutzeravatar
Irgendwer
Beiträge: 67
Registriert: 25.08.2021 19:05
Has thanked: 15 times
Been thanked: 30 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
25.05.2023 12:50
... mit welcher Umgebung programmierst du denn??
cc65/ca65

eigentlich versuche ich inzwischen soviel wie geht in cc65 zu schreiben und erst wenn es zeitkritisch wird, entweder cc65 zu verbessern :D 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!

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

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

Benutzeravatar
Dr. Irata
Beiträge: 890
Registriert: 24.08.2021 14:40
Has thanked: 110 times
Been thanked: 263 times
Kontaktdaten:

Re: Basic Plot / Drawto in Assembler

Beitrag von Dr. Irata »

... 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....

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast