Zahlen rechtsbündig ausgeben, aber wie?

Es gibt 11 Antworten in diesem Thema, welches 2.199 mal aufgerufen wurde. Der letzte Beitrag (5. Oktober 2011 um 10:17) ist von spider-j.

  • Hallo,

    Ich möchte gerne 16-bit positive integer Zahlen rechtsbündig auf den Bildschirm ausgeben und benutze dafür die Routine linprt ($bdcd). Da aber die zahlen 1 bis 5 Zeichen breit sind, kann ich sie nicht schön rechtsbündig ausgeben.
    Im BASIC würde dies so aussehen:

    Code
    10 l=len(str$(a))
    20 print tab(10-l)a

    Ich habe hier ein Assembler Beispiel wie die zahlen jetzt ausgegeben werden:

    Ausgegeben wird:

    Code
    searching for assemble.prg
    loading from $2000 to $20eb
    ready.
    sys8192
    1     the first value
    22    the second value
    333   the next value
    4444  and another one
    55555 the last value

    Gewünschte Ausgabe:

    Code
    1 the first value
       22 the second value
      333 the next value
     4444 and another one
    55555 the last value


    Hat jemand eine Idee wie das einfach gelöst werden könnte?

  • Hab mal ins ROM-Listing geschaut. Gibt keine Möglichkeit mit $bdcd die linksbündige Ausgabe zu umgehen.
    Wandel die Zahlen doch selbst in Dezimalzahlen um, dann kannst Du die Ausgabe ja völlig frei gestalten.
    Bitte melde dich an, um diesen Link zu sehen.
    (das untere Beispiel ist 16 Bit)

  • alt 2:

  • @spider-j
    Hab' das mit der BCD Darstellung probiert, und es funktioniert! :zustimm:
    Musste noch einiges anpassen wodurch es etwas mehr Code geworden ist.
    Außer chrout sind aber keine ROM-Routinen benutzt.

    Bitte melde dich an, um diesen Anhang zu sehen.

    tlr
    Ich habe gleich deine 2. alternative probiert da es bedeutend kürzer ist. :zustimm:
    Die Routine ist mir soweit klar, nur die ldx #$90 nicht.
    Aber macht nichts, läuft super!

    Bitte melde dich an, um diesen Anhang zu sehen.

    Die Routine verwende ich in ein MEM(ory) befehl und gibt als output:

    Code
    MEM
    $4001 $A000 $5FFF BAS 16385 40960 24575
    $4001 $402B $0028 PRG 16385 16427    40
    $402B $4040 $0015 VAR 16427 16448    21
    $4040 $407E $003E ARR 16448 16510    62
    $407E $9FE5 $5E67 FRE 16510 40933 24167
    $9FE5 $A000 $001B STR 40933 40960    27


    Die dezimale Zahlen werden immer rechtsbündig ausgegeben!

  • Ich hab auch noch ein bisschen drangebastelt, weil ich mich selber noch nie so richtig in 6510 ASM mit der Umrechnung beschäftigt habe. An der Uni wurde uns in Info vor allem das Horner-Schema zur Umrechnung gelehrt. Deswegen hab ich jetzt einmal eine stark durch Grahams 32 Bit Source von Codebase inspirierte Version zusammengeknüppelt.

    Hier mal der für die Umrechnung relevante Teil:

    Und hier der ganze restliche Kladderadatsch als ACME Sourcecode, wo ich noch eingebaut habe, dass beliebig viele Zahlen konvertiert werden können und wenn der Screen voll ist auf Tastendruck gewartet wird und so weiter:
    Bitte melde dich an, um diesen Anhang zu sehen.
    Hab darin auch ziemlich detailliert aufgedröselt, wie die oben erwähnte Schleife arbeitet.

    Und hier der ganze Spaß als fertiges PRG:
    Bitte melde dich an, um diesen Anhang zu sehen.

    EDIT: achso, außerdem liegen bei meiner Version die zu berechnenden Werte im Speicher des C64 und sind nicht nur als ACME-"Variablen" definiert. Würde wenigstens das noch so ähnlich bei Deinem Code anpassen, da hat man einfach mehr Freiheiten - z.B. könnte man die Zahlen vom User eingeben lassen oder per Laufwerk einlesen lassen oder als Binary in ACME einbinden oder oder oder....

  • Ich werde mir das morgen ansehen, sieht auf den ersten Blick sehr kompakt aus.

    EDIT: achso, außerdem liegen bei meiner Version die zu berechnenden Werte im Speicher des C64 und sind nicht nur als ACME-"Variablen" definiert. Würde wenigstens das noch so ähnlich bei Deinem Code anpassen, da hat man einfach mehr Freiheiten - z.B. könnte man die Zahlen vom User eingeben lassen oder per Laufwerk einlesen lassen oder als Binary in ACME einbinden oder oder oder....


    mein Code ist nur als Beispiel gemacht um das Problem zu isolieren.

    Bitte melde dich an, um diesen Anhang zu sehen.
    Der MEM Befehl von dem ich weiter oben sprach ist jetzt so weit „fertig“. Die Pointer der verschiedenen Speicherbereiche (siehe Bild) werden als HEX und Dezimal wiedergegeben.

  • Die Wiki –Erklärung geht mir ein bisschen zu weit, :) aber dein Programm ist mir soweit klar. Es stehen für mich schon einige nützliche Tipps drin.

    Hätte aber noch zwei Fragen:
    Wieso benutzt du Doppelpunkte hinter den Labeln? Hat das einen bestimmten Grund? Oder ist das mehr aus Gewohnheit zu anderen Assemblern?

    Was hat das mit „!align 1,0 ; datenanfang auf "gerade" adresse“ auf sich? Ist das für Geschwindigkeitsoptimierung oder den jmp(xxxx) Bug?

  • Wieso benutzt du Doppelpunkte hinter den Labeln? Hat das einen bestimmten Grund? Oder ist das mehr aus Gewohnheit zu anderen Assemblern?


    Wegen dem Syntaxhighlighting in gedit mache ich das (neuerdings) so, dass ich die globalen Labels mit Doppelpunkt versehe. Die werden dann noch einmal in einer anderen Farbe dargestellt. Mir ist auch letztens erst durch Sourcecodes anderer aufgefallen, dass ACME keinen Unterschied macht, ob ein Doppelpunkt folgt oder nicht, gedit hingegen schon.

    Zitat


    Was hat das mit „!align 1,0 ; datenanfang auf "gerade" adresse“ auf sich? Ist das für Geschwindigkeitsoptimierung oder den jmp(xxxx) Bug?


    Das ist kein Pagealign für Geschwindigkeit, bzw. Zyklengenauigkeit (das wäre !align 255,0). Den jmp Bug kenne ich nicht. Das schiebt eben die Daten auf eine gerade Adresse ($xx00, $xx02, $xx04, ...). Das ist nötig, weil ich ja sozusagen im Mainloop mit Pointern arbeite, die die aktuelle Zahl aus den Daten in den Zwischenspeicher kopiere. Sobald eine Zahl gelesen wurde, werden die beiden Pointer erhöht. Ob nun irgendwann eine Page bei den Daten überschritten wird, muss ich ja irgendwie prüfen. D.h. ich checke: ist das Lobyte des Pointers auf das Lobyte der Zahl $00, dann muss ich ebenfalls das Hibyte des Pointers auf das Lobyte der Zahl und das Hibyte des Pointers auf das Hibyte der Zahl erhöhen... :) klingt verwirrend, aber ich glaube das ist so der simpelste Weg.

  • Wegen dem Syntaxhighlighting in gedit mache ich das (neuerdings) so, dass ich die globalen Labels mit Doppelpunkt versehe. Die werden dann noch einmal in einer anderen Farbe dargestellt. Mir ist auch letztens erst durch Sourcecodes anderer aufgefallen, dass ACME keinen Unterschied macht, ob ein Doppelpunkt folgt oder nicht, gedit hingegen schon.

    Ja, das macht Sinn, das suchen geht so ein Stück einfacher. Ich nutze übrigens TextPad als Editor.

    Mit dem jmp(xxxx) Bug meinte ich das:

    D.h. ich checke: ist das Lobyte des Pointers auf das Lobyte der Zahl $00, dann muss ich ebenfalls das Hibyte des Pointers auf das Lobyte der Zahl und das Hibyte des Pointers auf das Hibyte der Zahl erhöhen...

    kapiere, eine nette Lösung ;)

  • Sieht übrigens hübsch aus, Deine Implementierung des MEM Befehls. Da man das ja eh für Basic braucht ist die gewählte Lösung mit den ROM-Routinen passend.
    Wegen dem align: im Grunde ist das ja tatsächlich ein bisschen so wie mit dem jmp(xxxx) Bug. 16Bit Werte, die beliebig (also gerade und ungerade) liegen können wären etwas umständlicher in der Handhabung. Ist mir auch erst aufgefallen, nachdem ich manchmal aufgrund von Ergänzungen im Code falsche Werte nach dem Pagewechsel hatte.