Eine Linie mit variabler Höhe printen

Moderator: Rockford

Antworten
Benutzeravatar
Dr. Irata
Beiträge: 1289
Registriert: 24.08.2021 14:40
Has thanked: 193 times
Been thanked: 434 times
Kontaktdaten:

Eine Linie mit variabler Höhe printen

Beitrag von Dr. Irata »

Hallo liebe kreative Gemeinde.

Wir bewegen uns in der Assembler-Welt!
Die Frage hört sich erstmal simpel an.

Ich möchte eine Linie auf den BS printen. Die Linie fängt immer auf der gleichen Höhe an (z.B.) Mitte des Bildschirmes und hat die Höhe x.
Der wert x wird am Anfang ausgelesen und bestimmt die Höhe der Linie. Bei jedem Durchgang ändert sich x und die Höhe der Linie variiert entsprechend. Klingt erstmal einfach mit einer entsprechenden Schleife und Rücksprung bis der Wert x erreicht wurde.
Aber so will ich es nicht machen!
Ich möchte Zeit sparen und will auf eine Schleife mit Sprung usw. verzichten.
Der Wert soll tatsächlich immer direkt in den BS-Speicher geprintet werden, und zwar x-Mal. Die Print-Kette müsste also so lang sein, wie x maximal sein kann (bzw. der Bildschirmoberrand erreicht wird) und dann aber in Abhängigkeit von x aufhört (z.B. mit einem RTS).

Meine 2 Ideen:
1. Idee: Nach jedem Print folgt ein NOP - mittels selbstmodifizierenden Codes speichert man ein RTS (in Abhängigkeit von x) an die richtig Stelle.
Könnte aufwendiger und langsamer für kleine x im Vergleich zur Schleife werden.
2. Idee: (Sehr Speicherintensiv). Für jeden möglichen x-Wert eine eigene Routine, die dann in Abhängigkeit von x klein bzw. recht groß sein kann. Ich rechne mit einem maximalen x-Wert von etwa 30-35.

Gibt es noch schnellere und bessere Wege bzw. Ideen??

Grüße
Peter

Benutzeravatar
Kveldulfur
Beiträge: 1060
Registriert: 17.08.2021 02:32
Has thanked: 504 times
Been thanked: 459 times
Kontaktdaten:

Re: Eine Linie mit vatiabler Höhe printen

Beitrag von Kveldulfur »

Dr. Irata hat geschrieben:
30.07.2025 09:51
1. Idee: Nach jedem Print folgt ein NOP - mittels selbstmodifizierenden Codes speichert man ein RTS (in Abhängigkeit von x) an die richtig Stelle.
Könnte aufwendiger und langsamer für kleine x im Vergleich zur Schleife werden.
Moin!

Wenn Du an der passenden Stelle ein RTS schreibst, musst Du dies aber auch wieder entfernen. Ich denke, dass der Aufwand nachher viel größer ist als bei einer normalen Schleife.

Beispiel 1:

Code: Alles auswählen

              LDX #$00					; 256 Durchläufe
              LDA #$ff
lp:
              STA (MEMSAV),X
              DEX
              BNE @-
Beispiel 2:

Code: Alles auswählen

              LDX #$00					; 256 / 4 = 64 Durchläufe
              LDA #$ff
lp:
              STA (MEMSAV),X
              DEX
              STA (MEMSAV),X
              DEX
              STA (MEMSAV),X
              DEX
              STA (MEMSAV),X
              DEX
              BNE @-
Beispiel 1 benötigt 256 Rücksprünge, während Beispiel 2 dieselbe Arbeit mit nur 64 Schleifendurchläufen erledigt.
So kann man Schleifen optimieren, ohne gleich unübersichtlichen Spaghetti-Code zu erzeugen.

Wichtig: Im Beispiel 2 muss der X-Registerwert stets durch 4 teilbar sein, da pro Schleife 4 Werte verarbeitet werden.

Laut ChatGPT benötigt Beispiel 1 insgesamt 2819 Zyklen, während Beispiel 2 nur 2235 Zyklen braucht – also rund 20 % schneller ist.

Interessant ist: Wenn man statt 4 gleich 8 Werte pro Schleife verarbeitet und dadurch nur noch 32 Durchläufe benötigt, kommt man auf 2147 Zyklen.
Das sind zwar etwa 24 % Ersparnis gegenüber Beispiel 1, aber nur rund 4 % mehr als bei Beispiel 2.

-> Es bringt also nur begrenzt Vorteile, immer mehr Werte pro Schleife zu bearbeiten – der zusätzliche Geschwindigkeitsgewinn wird mit jedem Schritt kleiner.

Grüße
Janko
Meine Projekte findest Du hier...

Benutzeravatar
Irgendwer
Beiträge: 141
Registriert: 25.08.2021 19:05
Has thanked: 25 times
Been thanked: 74 times
Kontaktdaten:

Re: Eine Linie mit vatiabler Höhe printen

Beitrag von Irgendwer »

Dr. Irata hat geschrieben:
30.07.2025 09:51
Gibt es noch schnellere und bessere Wege bzw. Ideen??
Eine Routine, welche die maximale Linienlänge zeichnet und einen berechneten Einsprung in die Routine, nach Abhängigkeit der Länge.
Das Ende bleibt immer gleich.

Benutzeravatar
Dr. Irata
Beiträge: 1289
Registriert: 24.08.2021 14:40
Has thanked: 193 times
Been thanked: 434 times
Kontaktdaten:

Re: Eine Linie mit vatiabler Höhe printen

Beitrag von Dr. Irata »

Danke Janko,
ich will aber die Schleife vermeiden und außerdem soll ja die Mauer in die Höhe und nicht in die Breite geprintet werden.

Benutzeravatar
Dr. Irata
Beiträge: 1289
Registriert: 24.08.2021 14:40
Has thanked: 193 times
Been thanked: 434 times
Kontaktdaten:

Re: Eine Linie mit vatiabler Höhe printen

Beitrag von Dr. Irata »

Irgendwer hat geschrieben:
30.07.2025 11:06
Dr. Irata hat geschrieben:
30.07.2025 09:51
Gibt es noch schnellere und bessere Wege bzw. Ideen??
Eine Routine, welche die maximale Linienlänge zeichnet und einen berechneten Einsprung in die Routine, nach Abhängigkeit der Länge.
Das Ende bleibt immer gleich.
Das ist die Idee, nach der ich gesucht habe... vielen Dank!!
Ich zeichne nicht von 0-x, sondern baue die Routine einfach genau andersrum auf und springe dann bei x ein - die Routine printet dann von x bis zum Wert 0
Perfekt, vielen Dank!!

Benutzeravatar
Dr. Irata
Beiträge: 1289
Registriert: 24.08.2021 14:40
Has thanked: 193 times
Been thanked: 434 times
Kontaktdaten:

Re: Eine Linie mit vatiabler Höhe printen

Beitrag von Dr. Irata »

Hier mal ein möglicher relativer Sprungcode:
Die Sprungweite (x) wird in den Akkumulator geladen und dann in die low-Byte Stelle des jmp Befehls eingespeichert.
Um es genau zu definieren habe ich ein org $2000 eingefügt, der low-Byte Wert steht dann bei $2001 - hier kommt die Sprungweite rein

Code: Alles auswählen

			lda #x		; x ist die Sprungweite			
			sta $2001
			
			org $2000			
			jmp *+0
			... code ...


Erhard
Beiträge: 1080
Registriert: 04.11.2021 15:52
Has thanked: 130 times
Been thanked: 332 times
Kontaktdaten:

Eine Linie mit variabler Höhe printen

Beitrag von Erhard »

Dr. Irata hat geschrieben:
30.07.2025 09:51
Ich möchte eine Linie auf den BS printen. Die Linie fängt immer auf der gleichen Höhe an (z.B.) Mitte des Bildschirmes und hat die Höhe x.
ich finde die Aufgabenstellung immer noch etwas uneindeutig.

Dreht es sich hier um eine gefüllte Fläche mit einer bestimmten Basislinie auf fester Postion und einer frei definierbaren Höhe?

Ferner ist zu beachten, daß die obere Linie eine niedrigere Bildschirmspeicheradresse hat als die Basislinie.

Ich würde meinen, daß es sehr von der Grafikauflösung abhängt, wie ein guter Assemblercode aussehen kann.

Bei GR.8 (192 Zeilen) zum Beispiel hätten wir ja ohne Schleife im schlimmsten Fall 192 Einsprungadressen für das Erzeugen jeweils einer Linie, oder sehe ich das falsch?

Selbst wenn die Basislinie in der Bildschirmmitte ist und die Fläche nur in eine Richtung wächst wären es noch bis zu 96 Einsprungadressen, oder?

Auch müßte der indexierte Sprung "rückwärts" gerechnet werden:

CLC
LDA #96
SBC Höhe

und hier müßte ja nun auch noch mit dem Abstand der Einsprünge untereinander multipliziert werden, damit ein JMP da landet wo es hin soll.

L00 (Code für gebe Linie in Bildschirmmitte-96 aus)
...
L94 (Code für gebe Linie in Bildschirmmitte-2 aus)
L95 (Code für gebe Linie in Bildschirmmitte-1 aus)
L96 (Code für gebe Linie in Bildschirmmitte aus)
RTS

Alternativ eine Sprungtabelle rückwärts:

*= $2000
JMPTBL .WORD L96-1, L95-1, L94-1 usw

und dann

LDA #Höhe
ASL
TAX
LDA JMPTBL,X
PHA
LDA JMPTBL+1,X (oder erst HI und dann LO ? )
PHA
RTS
Jede Info, die zu Hause auf meinem Rechner liegt habe ich unterwegs nicht verfügbar.
Jede Info, die im Netz liegt finde ich nicht wieder, wenn ich sie benötige.

Antworten

Wer ist online?

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