Hallo Besucher, der Thread wurde 6,7k mal aufgerufen und enthält 44 Antworten

letzter Beitrag von oobdoo am

Array umrechnen

  • Um was für Daten handelt es sich denn und wieviele Einträge hat das Array? Also welche Werte haben X und Y minimal und maximal?
    In Assembler erschlägt man Felder aller Art normalerweise mit den Indexregistern und Pointertabellen. Sehe gerade der Z80 hat sogar 16 Bit Indexregister, da kommt man ja schon recht weit mit.


    EDIT: geht es einfach um Screenkoordinaten?!?

  • Mein Array ist 20,25 groß.


    Beispiel: Dim ra(4,4)


    00,01,02,03
    04,05,06,07
    08,09,10,11
    12,13,14,15


    im Speicher würde es hintereinander stehen


    00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15


    Ich bastel aktuell in Excel mit der Formel, klappt aber nicht mit dem Beispiel y*x+x. :(


    Nachtrag: Ich geh mal Einkaufen, Kopp frei machen und Zucker fürs Hirn besorgen.

  • Die Indexregister des Z80 sind in der Praxis meist nutzlos. Und vermutlich wird man das hier gegebene Problem in Assembler völlig anders angehen als im ursprünglichen BASIC.


    Ich empfehle dringend ein Buch a la 'Maschinensprache für Einsteiger', um erstmal in die 'Denke' von Assemblerprogrammierung reinzukommen. Das muß nichtmal ein Buch speziell für den CPC sein- der hat nämlich derart mächtige Betriebssystem-Routinen, daß der Blick aufs Wesentliche eher verstellt wird...


  • Ich empfehle dringend ein Buch a la 'Maschinensprache für Einsteiger'


    Es geht gar nicht speziell um eni Assembler Problem, sondern um die reine Mathematik. Ich bekomme es ja nichtmal in Excel hin.
    Ist bestimmt wieder so einfach, das ich die Lösung oder den Fehler nicht sehe.

  • Zur genauen Berechnung der Position im Speicher mußt Du wissen, wieviele Bytes ein Element des Arrays hat. Ist es z. B. eine 16 Bit-Zahl, so wären dies 2 Bytes. Anhand dieser Elementgröße läßt sich dann die Anzahl Bytes pro y-Zeile errechnen. Die Formel wäre dann:


    speicher := y * (anzahl_der_elemente_pro Zeile * Elementgröße) + x * Elementgröße + Anfangsadresse


    Um die Multiplikationen zu vereinfachen, verwendet man gerne Vielfache von 2 für die Elementgröße als auch die Anzahl pro Zeile. Dann kann man anstelle der Multiplikationen einfache Shiftoperationen verwenden.


    Edit: Ohne Assembler wird die Berechnung einfacher. Wie Enthusi bereits schrieb:
    index := y * anzahl_der_elemente_pro_Zeile + x

  • Die Indexregister des Z80 sind in der Praxis meist nutzlos.


    Das weiß ich leider nicht. Aufm C64 wüsste ich sofort die simple Standardlösung. Lo/Hi Tabelle für Y Screenkoordinaten. Diese mit dem Y-Wert im X Indexregister auslesen in zwei ZP Tempregister und X-Wert ins Y Indexregister und lda/sta (zp),y (je nachdem). Ist das aufm Z80 nicht so einfach?

  • Ob in Excel VBA oder in einer anderen Programmiersprache: Matrizen kann man mit zwei verschachtelten Schleifen "ausrollen" (wir sagen dem "ausflatten").


    Im Excel VBA hast Du das sehr nützliche Offset Property in einem Range, um mit Matrizen und Koordinaten in der Form von x, y zu arbeiten.
    Das wird in der Form Range.Offset(y, x) mit y=Zeile und x=Spalte verwendet.
    Ich habe das oft für Kunden-Excel Sheets verwendet, um diese "auszuflatten" und daraus ein Textfile für eine weitere Verarbeitung als Schnittstelle zu generieren.


    Ich habe im Beispiel-Excel die Matrix mit dem Namen "Matrix" benamst und die Startposition mit dem Namen "LinearStart".
    Den Inhalt dieser Namen weise ich im VBA Code jeweils den Ranges "rMatrix" und "rLinearStart" zu. Daraus kann man dann die Spaltenbreite und Zeilenhöhe in Zellen für die beiden X / Y Loops ermitteln.


    Die Ausgabe in Excel ist zeilenweise sinnvoller als spaltenweise, aber ich habe das so eingebaut, dass man dies mit dem Boolean bOutputVertical steuern kann.
    Für die Weiterverarbeitung (z.B. Ausgabe in ein File) und auch damit man nicht so schnell ans Limit des Excels kommt (bei grossen Matrizen mit vielen Ausgabeelemente), ist eine zeilenweise Ausgabe erstrebenswerter.


    Ich habe mal das Beispiel-Excel Sheet mit dem VBA Code (wird über die Schaltfläche 'Linearisierung') gestartet. VBA-Editor anzeigen mit ALT+F11, im 'Modul1'.




    <Edit>Habe die Lösung hier trotzdem mal hier gepostet, hatte noch daran gearbeitet bevor Du es selbst gelöst hast. Ist vielleicht trotzdem nützlich für Jemanden... :whistling:


  • Die Multiplikation wollte ich weglassen.


    y * anzahl_der_elemente_pro_Zeile, also (y) 1-25 * 20 bleibt ja immer gleich. Die errechneten Werte werden fest kodiert und brauche dann nur x dazu addieren. Denke (hoffe) ich mal.

  • So, jetzt scheint es zu klappen. mx50.gif


    Aber die blöden High/Low Bytes, die bringen mich noch immer ins Stolpern


    ld a,(hl) gibts. Warum nicht ein ld de,(hl)? :gahh:


    Wenn man bei d,e ein 1,1 einsetzt, dann sollte der Akku am Ende eine 4 ausgeben.
    Nimmt man 20,25, dann sollte da eine 5 drine stehen.


  • Keine Ahnung ob das bei Z80 noch kürzer geht, wahrscheinlich aber schon.
    Bin aber erstmal froh das es überhaupt klappt.
    Damit dürfte heute die Bewegung der Spielfigur und der Restaurierung vom Hintergrund klappen.


    Was Du da geschrieben hast kann ich nicht lesen ohne 6510er Buch. ;)

  • Soviel ich weiß, kennt der Z80 leider keine Adressierungsart "Absolut mit Indexregister", lediglich "Indexregister mit 8-Bit Offset (IX+d)".
    Nun bin ich alles andere als ein Z80-Experte. Daher meine vorsichtige Anfrage, ob man das obige Programm vielleicht auch in dieser Form schreiben könnte (ungetestet):


    EDIT: Aber jetzt... ?

  • Gibt kein mov-Befehl in Z80.


    Nachtrag 01:
    Mit mov meinst wohl ld. Werde ich mal eben testen.


    Nachtrag 02:
    Gibt bei Koordinaten 20,25 ne 180 auf und keine 5. Läuft also nicht wie meins.

  • Es gibt kein add bc,bc. Hab da auf die schnelle was geändert, aber ob mein Gedanke jetzt richtig ist???




    Also mit 1,1 funktioniert es, aber nicht mit 20,25.