FOR-Schleife nach Z80
- oobdoo
- Erledigt
-
-
Guck dir den JR NZ - Befehl an.
LD BC,5000
loop: DEC BC
JR NZ loop: -
Guck dir den JR NZ - Befehl an.
LD BC,5000
loop: DEC BC
JR NZ loop:
Danke. Leider hab ich mich etwas unklar Ausgedrückt. Wenn ich das in Assembler nutze, dann rennt es mit Assembler-Speed.
Wie kann ich aber meine Schleife aus BASIC in Z80 nachbauen, so das beide die gleiche Zeit benötigen? -
Soweit ich das im Kopf habe, funzt das nicht, da DEC BC nicht Z beeinflusst.
Korrekt müsste sein:
LD BC,$irgendwas
loop:
DEC BC
ld A,B
OR C
JR NZ,loopBei 8-Bit-werten empfiehlt sich auch DJNZ (da wird B als Zähler genommen). Beispiel:
LD B,255
loop:
...mache irgendwas...
DJNZ loopBASIC-Timing... schwer. Entweder du bastelst Da NOPs rein (oder CALL $BD19 ), oder machst Doppelschleifen in Form von
LD HL,wert1
schleife1:
LD BC,wert2
schleife2:
DEC BC
LD A,B
OR C
JR NZ,schleife2
DEC HL
LD A,H
OR L
JR NZ,schleife1 -
Hach wenn ich das als Informatiker sehe, dreht sich immer mein Magen um....
Wenn Du eine Warteschleife / ein Delay brauchst, kommt es auch auf den Rechner an. Also z.B. ob Du an einen Timer rankommst/die Hardware einen Timer-Baustein hat, oder ob Du - noch viel besser - einen Interrupt benutzen kannst, und eine Echtzeituhr a la DALLAS Chip im Rechner hast. Denn eine reine Schleife (oder eine Schleife in einer Schleife) ist abhängig von der Taktfrequenz des Rechners und es lässt den armen Prozessor umsonst herumeiern und Energie verbraten.
Oder in Kurzform: Am Einfachsten ist natürlich eine Schleife mit zeitfressenden Opcodes (oder eine Schleife in einer Schleife) laufen zu lassen, aber elegant und energiebewusst ist was anderes
Gruss Peter
-
Stimmt natürlich.
Da es aber nur einen 4 MHz-CPC gibt, einTimer in dem Sinne auch nicht vorhanden ist, bleibt nichts anderes übrig.
Und extra für eine Schleife einen Interrupt einklinken ist dann doch etwas übertrieben -
Hach wenn ich das als Informatiker sehe, dreht sich immer mein Magen um....
Hast ja Recht. Aber bei einer 8-Bit 4Mhz Maschine ist es egal. Hauptsache die Zeit vergeht in einer Schleife.Hab im Web das gefunden:
CodeZ80 5seconds Timer for 10 MHz ORG 0000H LD SP,0FFFFH MAIN: CALL TIMER5TIMER5:LD E,35HJ60: LD B,0FFHJ61: LD D,0FFHJ62: DEC D JP NZ,J62 DEC B JP NZ,J61 DEC E JP NZ,J60 RET END
Aber noch nicht ausprobiert. -
energiebewusst
Das Argument liest man selten bei der Diskussion um Warteschleifenprogrammierung.Wenn man allein bedenkt, was man mit den ganzen verschwendeten Prozessortakten anstellen könnte. Von "Taktgefühl spenden bis hin zu BASIC-Programmierern mal ein paar Takte erzählen!
-
-
Verdammt, das Buch hab ich selber.
Danke für den Hinweis.
-
Wahrscheinlich denke ich so, weil ich vor einiger Zeit Windows-Programme geschrieben habe - dort verschwenderisch mit der Ressource CPU umzugehen, verbietet sich halt, weil das System nicht nur für einen Thread zuständig ist.
Man erzeugt so unnötig Last in einem Multitasking Betriebssystem. Klar, haben wir hier nicht - ein Z80 ist früheste Steinzeit im Vergleich, da braucht man nicht aufzupassen, eine CPU, eine Task.Das Argument "Energie verschwenden" finde ich heutzutage bei Systemen inzwischen auch sehr wichtig, wenn man alleine bedenkt wieviel Energie Google verbraucht, wird's einem richtig schlecht... 2,26 Milliarden Kilowattstunden ist kein Pappenstiel.
-
Ich hab mal ein DOS-Programm unter Windows 95 benutzt. Das war ähnlich programmiert.
Um rechts unten eine Uhr anzuzeigen, wurde einfach solange Zeit verbraten, bis endlich
so eine ewige Sekunde umgesprungen ist. Wenn der Benutzer grad nichts gemacht am
Programm, war das ganz schön anstrengend für die CPU. Blöd war halt, dass das zu 100%
CPU-Auslastung führt und Windows sich kaum mehr bedienen ließ.
Ich hab zwar keine Ahnung von CPC-Programmierung, aber unter DOS konnte man sich
ganz leicht in den Timer-Interrupt reinhängen und den so für Delays nutzen. -
Soweit ich das im Kopf habe, funzt das nicht, da DEC BC nicht Z beeinflusst.
Ups, hab schon zu lange nicht mehr Z80 programmiert...
"Energie sparen" - naja, bei einem Z80 dürfte sich der Stromverbrauch kaum ändern, ob der jetzt alle 4 Taktzyklen einen NOP ausführt oder was rechnet...
Und natürlich, auf einem CPC mit garantiert 4 MHz Taktfrequenz funzt so eine Schleife sicher und ist am einfachsten programmiert.
Man muss natürlich bedenken, dass bei anderen Vorraussetzungen, z.B. Portierung des Programms auf ein anderes Z80-System, was dann z.B. mit 8 oder 12 MHz läuft, das Timing wieder nicht passt. Bei 8 MHz rennt es doppelt so schnell. Da ist immer ein externer Timer besser.
Multitasking-Betriebssysteme haben meist extra Systemaufrufe, da in der Zeit, die überbrückt werden soll, die Prozessorleistung auf die anderen Prozesse verteilt werden kann, genau so wie beim Warten auf eine Eingabe des Benutzers oder aif Rückmeldung irgendeiner Hardware.
Concurrent CP/M hat z.B. das Kommando "P_DELAY", bei dem man die Anzahl "Ticks", die das System warten soll, angeben kann. Ist aber auch nicht ganz neutral, da die Ticks - laut Doku von DR - vom Netzteil kommt, sind also bei uns 50 Ticks pro Sekunde, in den USA dagegen 60.
Aber dieser Aufruf führt dazu, dass der Scheduler das Programm solange stoppt, bis die Zeit abgelaufen ist.