Hallo, guten Tag. Ich brauche bitte eine Schleife für 76800 Byte. Das ist mein Anfang. Ich habe 256x256 schleifendurchgänge. Es fehlen noch 34 Schleifen. Wie kann man die bitte dort zwischen den 2x loop mit unterbringen oder muss ich am ende eine schleife mit 34x256 dranhängen? ------------------------------ ldx #$00 loop1: ldy #$00 loop: lda #45 sta $9f23 iny bne loop inx bne loop1 oder eine Schleife von 34x256 dranhängen? ------------------------------- Danke.
:
Bearbeitet durch User
Nö, da fehlen dir noch 44. Da aber nur ein fester Wert (45) an eine absolute Adresse (0x9f23) geschrieben wird:
1 | lda #45 |
2 | ldx #0 |
3 | loop1: |
4 | ldy #150 |
5 | loop: |
6 | sta $9f23 |
7 | sta $9f23 |
8 | dey |
9 | bne loop |
10 | dex |
11 | bne loop1 |
Du könntest auch Bytes auf zero page verwenden, z.B. $10 und $11 lda #44 sta $10 lda #01 sta $11 ldy #$00 loop: lda #45 sta $9f23 iny bne loop dec $10 bne loop dec $11 bpl loop
Welchen Sinn macht es 76800 (vermutl. verschiedene) Werte an eine einzige Adresse zu schreiben?
Kurt schrieb: > Welchen Sinn macht es 76800 (vermutl. verschiedene) Werte an eine > einzige Adresse zu schreiben? 320 * 240 = 76800 Klingelts?
Peter B. schrieb: > Ich brauche bitte eine Schleife für 76800 Byte. Wie wär's denn mit zweimal 38400?
Kurt schrieb: > Welchen Sinn macht es 76800 (vermutl. verschiedene) Werte an eine > einzige Adresse zu schreiben? Wenn es eine Peripherie-Adresse ist (VIA,RIOT), könnte zB. jedes mal ein Strobe erzeugt werden.
Norbert schrieb: > könnte zB. jedes mal ein Strobe erzeugt werden. Das hilft überhaupt nichts da es nicht das Problem löst über die 16-Bit Grenze von 65535 hinaus zählen zu müssen.
Wastl schrieb: > Das hilft überhaupt nichts da es nicht das Problem löst über > die 16-Bit Grenze von 65535 hinaus zählen zu müssen. Wer soll denn da außer der CPU noch zählen? Einfach einen Sack voller gleicher Werte zB. an ein Display senden um es mit einer Farbe oder einem Muster zu initialisieren. Das Display wird dafür sorgen die eingehenden Daten angemessen zu verarbeiten.
Norbert schrieb: > ............... Ich sehe schon, du bist in der Assembler-Programmierung von 8-Bit Prozessoren voll fit.
Wastl schrieb: > Norbert schrieb: >> ............... > > Ich sehe schon, du bist in der Assembler-Programmierung von > 8-Bit Prozessoren voll fit. Sag mal, hast du getrunken? Schau dir mal meinen Code oben an. Und dann versuche einfach mal 150 × 2 × 256 zu rechnen!
Was Peter macht, ist wie immer voll geheim. Ich glaube, es geht darum: https://www.8bitcoding.com/p/vera-overview.html?m=1
:
Bearbeitet durch User
Wastl schrieb: > Das hilft überhaupt nichts da es nicht das Problem löst über > die 16-Bit Grenze von 65535 hinaus zählen zu müssen. Das ist korrekt, mit x und y lassen sich 256*256 = 65536 Werte zählen. Um bis 76800 zu zählen kommt man also um eine zweite Schleife nicht herum. Verstehe nur den Sinn des ganzen nicht...
Kurt schrieb: > Verstehe nur den Sinn des ganzen nicht... Du musst dich nur ein wenig mit der Ansteuerung von Hardware beschäftigen, dann wird das…
Das ist eine Grafikkarte, siehe Link weiter oben. Man könnte auch einfach mehrfach schreiben und entsprechend weniger wiederholen.
Man darf auch in Assembler weiter rechnen als nur bis 255. Dazu werden mehrere 8Bit Variablen zusammen gefaßt. Im einfachsten Fall nimmst Du ein C-Programm, legst eine Schleife mit 32Bit Variable an und läßt es nach Assembler übersetzen.
Peter D. schrieb: > Man darf auch in Assembler weiter rechnen als nur bis 255. Dazu werden > mehrere 8Bit Variablen zusammen gefaßt. > Im einfachsten Fall nimmst Du ein C-Programm, legst eine Schleife mit > 32Bit Variable an und läßt es nach Assembler übersetzen. Recht und schön, funktioniert aber nicht mit beim 6502. Der hat nur einen 8 Bit Datenbus und 16 Bit breiten Adressbus. Der 6502 kann auch Arrays grösser 256 nur blockweise ansprechen.
Kurt schrieb: > Recht und schön, funktioniert aber nicht mit beim 6502. Wäre schön wenn hier nur Leute schrieben, die sich zumindest mal auf weniger als 500m einem Assembler genähert hätten. Über handgedengelten Maschinencode will ich schon gar nicht schreiben. Aber – dies ist ja mittlerweile das Arduino Forum - was will man erwarten… PS: Es gab auch mal einen 4004 Prozessor. Der konnte dann wohl nur bis fünfzehn zählen…
:
Bearbeitet durch User
Kurt schrieb: > Der 6502 kann auch Arrays grösser 256 nur blockweise ansprechen. Es geht hier nicht um Arrays, sondern um Wiederholungen. Und Zähler kann man so breit aufbauen, wie man Speicher hat.
Mario M. schrieb: > Es geht hier nicht um Arrays, …und selbst wenn es um Arrays ginge, selbst dann wäre seine Aussage falsch. Und zwar so falsch das noch nicht einmal das Gegenteil richtig wäre. Der 6502 kannte natürlich auch indirect,indexed und ebenso indexed,indirect. Und damit konnte man den kompletten Adressbereich ohne – wie war das, "Blöcke" – abarbeiten.
Kurt schrieb: > Recht und schön, funktioniert aber nicht mit beim 6502. Der hat nur > einen 8 Bit Datenbus und 16 Bit breiten Adressbus. Hat der 8051 auch nur. Trotzdem benutze ich dort problemlos 32Bit long und 32Bit float Variablen. Der Compiler bastelt sich das automatisch aus 4 Byte im RAM oder in Registern zusammen, in Assembler muß man das eben händisch machen.
:
Bearbeitet durch User
Peter D. schrieb: > in Assembler muß man das eben händisch machen. Schön ist das nicht, aber „wat mutt, dat mutt“. Um eine weitere 8-Bit-Familie ins Spiel zu bringen, ein beispielhaftes 32-Bit-Macro für PIC (wie ich die Syntax hasse, einfach nur hässlich, wie schön war doch Z80):
1 | ;-------------------------------------------------------------------------- |
2 | ; MACRO to perform 32-bit addition - adds the four bytes at src |
3 | ; to the four bytes at dst (most significant bytes first), returns the |
4 | ; result in dst with src unchanged and the carry flag set if overflow |
5 | ;-------------------------------------------------------------------------- |
6 | |
7 | ADDx32 MACRO src, dst ;dst := dst + src |
8 | |
9 | bcf STATUS, C |
10 | movf src+3, w |
11 | btfsc STATUS, C |
12 | incfsz src+3, w |
13 | addwf dst+3, f |
14 | movf src+2, w |
15 | btfsc STATUS, C |
16 | incfsz src+2, w |
17 | addwf dst+2, f |
18 | movf src+1, w |
19 | btfsc STATUS, C |
20 | incfsz src+1, w |
21 | addwf dst+1, f |
22 | movf src+0, w |
23 | btfsc STATUS, C |
24 | incfsz src+0, w |
25 | addwf dst+0, f |
26 | |
27 | ENDM |
:
Bearbeitet durch User
Peter D. schrieb: > Der Compiler bastelt sich das automatisch aus > 4 Byte im RAM oder in Registern zusammen, in Assembler muß man das eben > händisch machen. Genau. Und der funkheld wird das wohl nie wirklich lernen. Der versucht sich mit unzähligen Architekturen, begreift aber offensichtlich bei keiner davon auch nur irgendetwas. Crackhead oder Troll? Ich bin mir trotz der langen Historie seiner Bemühungen immer noch nicht sicher.
Norbert schrieb: > und selbst wenn es um Arrays ginge, selbst dann wäre seine Aussage > falsch. > Und zwar so falsch das noch nicht einmal das Gegenteil richtig wäre. > Der 6502 kannte natürlich auch indirect,indexed und ebenso > indexed,indirect. > Und damit konnte man den kompletten Adressbereich ohne – wie war das, > "Blöcke" – abarbeiten. Achso, das stimmt also nicht? Wie gross ist denn das x und y Register vom 6502? Und wenn ich jetzt einen Speicherblock (Array) ansprechen will, geht das dann auf einen Rutsch oder blockweise? Und wenn ich jetzt indirekt adressiere z.B mit <lda ($45),y inc y...> kann er dann weiter zählen als bis zum Maximum des y Wertes? Spätestens dann muss der Wert von im Beispiel $45 geändert werden um den restlichen Speicher zu adressieren.
Ich sehe schon, du hast dein Wissen nun um eine Seite erweitert. Zumindest hast du erkannt, das man die Basisadresse auf die in der ZP verwiesen wird, beliebig ändern (zB. inkrementieren) kann. Das ist sogar der tiefer liegende Sinn des ›indirect‹ Man kann diese auch 2^16-1 × inkrementieren (oder ein Gemisch aus Basis und Index). Das hatte MOS (der Hersteller) schon Mitte der Siebziger erkannt und in ihrem ›Programming Manual‹ freundlicherweise sehr sauber dokumentiert. Du jedoch schriebst: Kurt schrieb: > Der 6502 kann auch > Arrays grösser 256 nur blockweise ansprechen. MOS ist da eben anderer Meinung. Wenn man sich allerdings explizit nur auf Änderung der X/Y Register versteifen möchte, dann bleibt man in seinem 8Bit Denken verfangen… Du denkst offensichtlich an ›absolute indexed addressing‹ und ja, damit kann man nur 256 Bytes mittels X oder Y Register ansprechen. Es gibt aber mehr… Fakt bleibt, Arrays (egal welcher Größe bis zum maximalen Adressraum) können Byte-weise angesprochen werden. Sowohl ›indirect‹ als auch ›indirect indexed‹. Der Programmierer hat da freie Wahl. Einfach indem er den ›indirect‹ Part und vielleicht auch noch den ›indexed‹ Part ändert. Nu wird's aber langweilig…
Kurt schrieb: > Und wenn ich jetzt indirekt adressiere z.B mit <lda ($45),y inc y...> > kann er dann weiter zählen als bis zum Maximum des y Wertes? Wenn man nicht darauf besteht, Y hochzählen zu lassen, sondern das Bytepaar {$45/$46} hochzählen lässt, dann geht das durchaus. Nicht nur blockweise. Die Zero-Page des 6205 kann man dabei als erweiterte Registerbank betrachten, ähnlich wie beim AVR der Speicherbereich 0x00-0x1f, der dort explizit auf die Register r0..r31 gemapt ist. Kurt schrieb: > Welchen Sinn macht es 76800 (vermutl. verschiedene) Werte an eine > einzige Adresse zu schreiben? Zugriff auf Speicher, die größer als die 16-Bit des Adressbusses des 6502 sind. Hat man auch bei Z80 oder 8051 schon so gemacht. Grafikkarten, Massenspeicher, Peripherie, ... Drittens: Zählen (um das ging es dem TO) kann der 6502 so weit, wie man Speicherstellen benutzt, also auch 32-Bit oder 64-Bit oder noch längeres, so weit der Speicher reicht. Man muss sich nur davon lösen, das alles ausschließlich mit A oder Y oder X machen zu wollen, sondern die Mittel nutzen, die der Prozessor sonst noch zur Verfügung stellt. HTH, (re)
Re schrieb: > Wenn man nicht darauf besteht, Y hochzählen zu lassen, sondern das > Bytepaar {$45/$46} hochzählen lässt, dann geht das durchaus. Nicht nur > blockweise. Klar kann man damit eine 16 bit Zahl darstellen, aber wie gross kann denn der Wert von $45 oder $46 werden? Spätestens bei $00 oder $ff muss einer der beiden Zeiger geändert werden wenn weiter gezählt werden soll.
Kurt schrieb: > Spätestens bei $00 oder $ff muss > einer der beiden Zeiger geändert werden wenn weiter gezählt werden soll. Das ist ein 16-Bit-Zeiger, der da in %45/$46 abgelegt ist: https://web.archive.org/web/20221112220344if_/http://archive.6502.org/datasheets/synertek_programming_manual.pdf [Seite 87] (re)
Es ist EIN Zeiger (wie von Re schon geschrieben wurde)!
1 | version1: |
2 | ldx #10 |
3 | stx ARRPTR+1 ; high array beginnt bei $1000 |
4 | ldx #0 |
5 | stx ARRPTR ; low |
6 | loop1: ; 61440×, bis Adresse $FFFF |
7 | lda (ARRPTR,X) ; Array byteweise lesen |
8 | eor #$ff ; und bits invertieren |
9 | sta (ARRPTR,X) ; Array byteweise schreiben |
10 | inc ARRPTR ; nächste Adresse im Array |
11 | bne loop1 |
12 | inc ARRPTR+1 |
13 | bne loop1 |
14 | |
15 | version2: |
16 | ldx #10 |
17 | stx ARRPTR+1 ; high array beginnt bei $1000 |
18 | ldx #0 |
19 | stx ARRPTR ; low |
20 | loop2: ; 61440×, bis Adresse $FFFF |
21 | lda (ARRPTR,X) ; Array byteweise lesen |
22 | eor #$ff ; und bits invertieren |
23 | sta (ARRPTR,X) ; Array byteweise schreiben |
24 | inx ; nächste Adresse im Array |
25 | bne loop2 |
26 | inc ARRPTR+1 |
27 | bne loop2 |
Entweder nur über ARRPTR oder über Kombination mit X (spart 3 cycles pro Schleife)
:
Bearbeitet durch User
Natürlich ist das ein Zeiger, wo hasst in dein Beispiel die beiden Pointer definiert? Und dein Pogramm macht genau das, was ich die ganze Zeit hier schreibe. Du lädst in dem ersten Beispiel x mit 00 und zählst bis ff hoch. Anschliessend erhöhst du das Highbyte deines Pointers. Und weil das Highbyte des Pointers nicht ausgewertet wird, haben wir jetzt eine Enlosschleife.
Kurt schrieb: > wo hasst(sic) in dein Beispiel die beiden > Pointer definiert? Oh ja, das ist natürlich ein schwieriger Code-Komplex. Das liefere ich nach.
1 | ARRPTR = $40 |
oder auch gerne irgendwo sonst in der ZP. Und es hat auf die Diskussion keinerlei Einfluß. Lenkt aber vielleicht etwas ab. Und es ist immer noch EIN Zeiger. Nur EINER! Und der ist 16Bit breit. Kurt schrieb: > Und weil das > Highbyte des Pointers nicht ausgewertet wird, haben wir jetzt eine > Enlosschleife. Das ist natürlich auch schwierig.
1 | inc ARRPTR+1 |
2 | bne loop1 |
Ich hoffe jetzt inständig das ich das Z-Flag nicht erklären muss. Zum Rest deiner Ausführungen: Kurt schrieb: > macht genau das, was ich die ganze Zeit hier schreibe. Nein, das hast du nicht geschrieben! Ich habe aber jetzt wirklich keine Lust mehr auf dein ständiges Herauswinden.
Norbert schrieb: > Ich hoffe jetzt inständig das ich das Z-Flag nicht erklären muss. Sorry, da hast du recht, ist ein Fehler von mir. Norbert schrieb: > ARRPTR = $40 ARRPTR = $40, das ist eine 8 bit Adresse -- ARRPTR+1 = $41, ebenso 8 bit, beide zusammen 16 bit und nicht einer allein. Wenn du mit 16 bit rechnen willst, brauchst du Low und High Byte Man könnts auch direkt schreiben: lda $40 - eor #$ff - sta $40 und später inc $41 Schreib jetz auch nix mehr, iss mir einfach zu dumm...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.