Hallo, guten Tag.
wie kann man bitte die äußere Schleife anhängen für den Z80 ?
Danke.
--------------------------
loop1
....... schleife mit 256 durchgänge wobei $c000 immer um 256 erhöht
wird
ld b,16
ld hl,$c000
loop:
ld a,3
ld (hl),a
inc hl
djnz loop
zurück zu loop1
--------------------------
Gibt doch noch die D E Register?
Die könnte man doch auch rückwärts zählen lassen. Nur den Sprung muss
man anders auslegen, da djnz nur auf B gilt. Also dec und Sprung
einzeln.
Mario M. schrieb:> Es gibt viele Möglichkeiten, dies wäre eine:
Deshalb heisst die Architektur des Z80 CISC - es gibt eher viel zu viele
Befehle.
Georg
Peter B. schrieb:> wie kann man bitte die äußere Schleife anhängen für den Z80 ?
Man kann auch B vor der inneren Schleife pushen und danach wieder
poppen, damit beide DJNZ nutzen können.
hex-fan schrieb:> MaWin schrieb:>>> Man kann auch B vor der inneren Schleife pushen>> Push/Pop ist immer 16 bit. Also BC.
Der Assembler könnte das anders sehen, wenngleich "push b" eher
8080-Syntax ist.
----------------------------------
Willst Du wirklich über 64k verteilt immer die ersten 16 Byte jeder
256-Byte-Page mit $03 überschreiben ?
----------------------------------
Nein die Werte werden sich später ändern , die dann von einem Speicher
ausgelesen werden.
Ich möchte erstmal einen Grund in meine Frage reinbekommen.
Der Z80 hat sehr viele Befehle.
Danke.
Peter B. schrieb:> Ich möchte erstmal einen Grund in meine Frage reinbekommen.> Der Z80 hat sehr viele Befehle.
Dann beschränke Dich zunächst auf den Befehlssatz des 8080.
Ich habe mir damals (1982) Rodnay Zaks "Die Programmierung des Z80"
gekauft.
Da steht alles drin, Register und Befehle. Ich habe dann die Beispiele
nachprogrammiert, und viel gelernt.
Das Buch ist selbst 2022 bei Amazon erhältlich:
https://www.amazon.de/Programmierung-Z80-Rodnay-Zaks/dp/388745006X
Warum nicht auch heute was lernen?
Mein Exemplar von damals steht immer noch im Bücherschrank.
Peter B. schrieb:> loop1> ....... schleife mit 256 durchgänge wobei $c000 immer um 256 erhöht> wird
Also mir ist das eigentliche Anliegen noch immer zu unverständlich. Du
willst 256 mal bittesehr WAS? Falls du die Adresse $C000 meinst, dann
geht diese etwa so $C000, $C100, $C200 usw. und füllt damit den gesamten
Speicher - allerdings jeweils nur die ersten 16 Byte in jedem 256 Bytes
großen Abschnitt. Was soll das werden?
W.S.
Es ist für den N-GO für den layer2.
Ich möchte in einer SChleife dieses $c000 in hl immer um 256 erhöhen.
Dieses Grundprinzip suche ich für den Z80.
Kann auch nur 10x sein , aber wie?
Danke.
Irgendwie riecht das hier verdammt nach Gruft!
Ohne nachzusehen, hat man um Speicher zu füllen das nicht irgendwie mit
LDIR gemacht?
Peter B. schrieb:> Der Z80 hat sehr viele Befehle.
Nö.
Moin,
michael_ schrieb:> Peter B. schrieb:>> Der Z80 hat sehr viele Befehle.>> Nö.
Doch!
Ohhh!
Gegenueber einem 6502 hat der Z80 doch deutlich mehr...
Aber's gibt sicher auch Prozessoren mit noch mehr Befehlen als der Z80
hat.
Zur aeusseren Schleife kann ich auch nur sagen:
"Erlaubt ist, was gefaellt" und "Viele Wege fuehren nach Rom".
Gruss
WK
Vielleicht kann man mir bitte helfen ,wie ich einen zähler bei loop3
setze?
Diese hl erhöhen um 256 habe ich jetzt gefunden. Nun fehlt mir eine
Zählschleife für loop3 dazu.
Danke.
loop3:
...............................
ld bc,256
ld hl,$c000
add hl,bc
ld b,16
loop1:
ld a,252
ld (hl),a
inc hl
djnz loop1
..........................
djnz loop3
Percy N. schrieb:> Dann beschränke Dich zunächst auf den Befehlssatz des 8080.
Würde ich so nicht sagen. Die Mnemomics von Intel sind grausam, da hat
Zilog echte Verbesserungen gebracht.
Ok, in der Pubertät fanden wir den Befehl zum Und-Verknüpfen des
Akkumulators mit dem L - Register noch lustig...
Peter B. schrieb:> Diese hl erhöhen um 256 habe ich jetzt gefunden
"inc h" hätte für diesen Fall gereicht, aber das Laden von HL muss aus
der Schleife raus, sonst schreibt er immer ab $C100.
Peter B. schrieb:> Ich möchte in einer SChleife dieses $c000 in hl immer um 256 erhöhen.> Dieses Grundprinzip suche ich für den Z80.
Das ist doch pipi-einfach:
Was ist HL? Ein Pseudo-16-Bit-Register aus den beiden 8-Bit-Regisern H
und L.
Und dabei ist das H-Register das High-Byte und das L-Register das
Low-Byte. Wahnsinnig schwierig zu merken...
Und wenn man ein 16-Bit-Register um 256 erhöht, was passiert dann?
Auch ganz einfach: Das High-Byte wird um exakt eins erhöht.
Also ist die Antwort auf Deine Frage:
1
inc h
Peter B. schrieb:> ld a,3> ld (hl),a
Den Akku kannst Du Dir sparen. Du kannst mit HL auch direkt schreiben:
1
ld (hl),3
Mario M. schrieb:> push bc> push hl
Meine Güte! Der Z80 hat Register und Befehle, da muss doch nicht so
gedankenlos programmieren:
1
ld h,$c0 ; High-Byte Startadresse
2
ld c,10 ; Anzahl Blöcke
3
4
loop1:
5
ld l,0 ; Startadresse auf 256-Byte-Grenze ausrichten
Percy N. schrieb:> Der Assembler könnte das anders sehen, wenngleich "push b" eher> 8080-Syntax ist.
Hatte ich erwähnt, dass ich die Mnemonics von Intel Murks finde ?
U.A. weil der (zugegeben irreführende) Name nichts daran ändert, dass
der Befehl das BC - Registerpaar auf den Stack ablegt.
FOp schrieb:> Percy N. schrieb:>>> Dann beschränke Dich zunächst auf den Befehlssatz des 8080.>> Würde ich so nicht sagen. Die Mnemomics von Intel sind grausam, da hat> Zilog echte Verbesserungen gebracht.
Das mag sein, nur besteht der Befehlssatz des Prozessors nicht aus
irgendwelchen Mbemonics.
FOp schrieb:> Hatte ich erwähnt, dass ich die Mnemonics von Intel Murks finde ?
Nein, Du hast nur erkennen lassen, dass Du sie für einen Befehlssatz
hältst.
Experte schrieb:> Mario M. schrieb:>> push bc>> push hl>> Meine Güte! Der Z80 hat Register und Befehle, da muss doch nicht so> gedankenlos programmieren:
Die registerbasierte Schreibweise hatte ich in meinem ersten Post schon
gezeigt, aber der TO hat es entweder nicht gelesen oder nicht verstanden
bzw. nicht kommentiert. Solange er nicht genau sagt, was er will, kann
man keine optimale Version erstellen. Es kann ja z.B. auch sein, dass er
das Füllbyte an die Routine übergeben möchte.
Mario M. schrieb:> Solange er nicht genau sagt, was er will, kann> man keine optimale Version erstellen.
Vielleicht weiß er auch nur nicht, wie man 16-Bit-Arithmetik mit dem Z80
macht. Da muss man natürlich etwas mehr von Hand machen weil man alles
durch den Akku prügeln muss. Hier einige Beispiele:
16-Bit-Register um eins erhöhen:
1
inc hl ; oder bc, de, ix, iy
8-Bit-Konstante zu einem beliebigen 8-Bit-Regiser addieren:
1
; 8-Bit-Register C + 8-Bit-Konstante
2
3
ld a,c ; Berechnungen gehen immer über den Akku
4
add a,123 ; Konstante 123 addieren
5
ld c,a ; Ergebnis aus dem Akku ins Register C kopieren
8-Bit-Konstante zu einem 16-Bit-Register addieren:
1
; 16-Bit-Register HL + 8 Bit Konstante
2
3
ld a,l ; Low-byte von HL
4
add a,123 ; Konstante 123 addieren
5
ld l,a ; Ergebnis zurück ins Low-byte von HL
6
jrnc fertig ; Wenn kein Carry-Flag gesetzt, ist Addition fertig
7
inc h ; Übertrag: High-Byte von HL erhöhen
8
fertig:
Um eine 16-Bit-Konstante zu einem 16-Bit-Register zu addieren, ist wenig
mehr Aufwand nötig:
1
; 16-Bit-Register DE + 16-Bit-Konstante
2
3
ld a,e ; Low-Byte von DE
4
add a,$34 ; Low-Byte von $1234 addieren
5
ld e,a ; Ergebnis zurück ins Low-Byte von DE
6
ld a,d ; High-Byte von DE
7
addc a,$12 ; High-byte von $1234 und Carry-Flag addieren
8
ld d,a ; Ergebnis zurück ins High-Byte von DE
Und so fort. Es ist doch nicht weiter schwer, oder?
Experte schrieb:> Vielleicht weiß er auch nur nicht, wie man 16-Bit-Arithmetik mit dem Z80> macht.
Ja, das weiß nicht jeder, dabei konnte schon der 8080 16- bit-Adfitionen
mit HL als Zielregister ...
Schwer ist es mit dem Zahlen nicht , die zu bearbeiten.
Ich finde die verschiedenen Lösungen für die Schleifen nicht so richtig.
Welches der Verantwortliche Zähler ist von den Registern usw.
Wie kann man dann bitte buffer nutzen? :
buffb:
db 0
buffw
dw 0
Kann man die auch als Ersatz nehmen statt : push / pop ?
Wäre für mich übersichtlicher und sauberer.
Bei push und pop weiss ich dann nicht woran das liegt wenn das Programm
andere Daten schickt die nicht stimmen oder abstürzt.
Wie geht das mit dem buffer und welches Register nimmt man bitte dafür?
Den Grundsatz der Register mit befüllen und schieben , ldir , addieren ,
subtrahieren ist kein Problem.
Ich suche eben das arbeiten mit den verschiedenen Schleifen formen und
das arbeiten mit buffer statt dieses push pop.
Das steht nicht so drin im Buch.
Die vielen Seiten dort drin wie ein Byte aufgebaut ist , das ist
Verschwendung im Buch. Bei speziellen Fragen weicht der Autor auch aus.
Peter B. schrieb:> Bei speziellen Fragen weicht der Autor auch aus.
Warum auch nicht, aufgrund des des hervorragenden Inhaltes sollte man
spezielle Fragen selber beantworten können.
Außerdem kann man auch lernen, wie man Flussdiagramme zeichnet, was
wiederum dabei hilft, gute Schleifen zu organisieren/konstruieren.
So ein Buch hätte ich mir früher für den Atari ST gewünscht, stattdessen
aber sehr viel anderes irrelevantes Zeugs gefunden.
Abgesehen davon, dass oben auch schon ganz gute Hinweise stehen, fällt
mir aber noch ein, es könnte sich lohnen, sich gute Z80 Quellcodes zu
besorgen.
Außerdem kann man auch noch (Windows/DOS) debug zu Hilfe nehmen, um
gewisse Ideen auszuprobieren.
http://www.asmirvine.com/debug/Debug_Tutorial.pdf
So etwas geht nicht mit dem Debugger.
So sehen meine Programme aus für den N-GO/NEXT
-----------------------
program Layer2;
@use "screen"
@use "text/txt"
@use "memory"
@use "Next"
@use "compression"
var
y,z,p : Byte;
zp:pointer;
x,ac,ad,af : integer;
procedure Delay(del: Byte);
begin
while (del > 0) do
begin
Memory_VSync();
del := del - 1;
end;
end;
procedure plotlayer();
begin
asm("
L2_BANK equ 32
ld bc,#243b
ld a,$56
out (c),a
ld bc,#253b
ld a,L2_BANK*2
out (c),a
ld hl,$c000+16
ld b,10
loop2:
push bc
push hl
ld b,16
loop1:
ld a,252
ld (hl),a
inc hl
djnz loop1
pop hl
ld bc,256
add hl,bc
pop bc
djnz loop2
ld bc,#243b
ld a,$12
out (c),a
ld bc,#253b
ld a,L2_BANK
out (c),a
ld bc,#243b
ld a,$69
out (c),a
ld bc,#253b
ld a,$80
out (c),a
");
end;
begin
plotlayer();
Loop();
end.
------------------------------
procedure UpdateSprite();
begin
asm("
ld a,0 ; get ID spriteid
ld bc, $303b ; selct sprite slot
out (c), a
ld bc, $57 ; sprite control port
ld a,100 ; attr 0 = x (msb in byte 3)
out (c), a
ld a,50 ; attr 1 = y (msb in optional byte 5)
out (c), a
ld d,0 ; attr 2 = now palette offset and no rotate and mirrors
flags send byte 3 and the MSB of X
ld a,0 ; msb of x
and 1
or d
out (c), a ; attr 3
ld a,128+5 ; attr 4 = Sprite visible and show pattern
or 192 ; bit 7 for visibility bit 6 for 4 bit
out (c), a
ld a,10 ; attr 5 the sub-pattern displayed is selected by N6 bit
in 5th sprite-attribute byte.
out (c), a ; att
");
end;
-----------------------------
....sich gute Z80 Quellcodes zu
besorgen.
Dieses ist Relativ zu meinem Programm , es geht nicht mit ähnlichen
Programmen. Ich finde keine ASM für meine Fragen mit dem Layer2 usw. und
den Bänken.
---------------------
So ein Buch hätte ich mir früher für den Atari ST gewünscht,
---------------------
Davon gab es zwei verschiedene Bücher , jetzt auch noch mit PDF.
Ich habe die beiden als PDF und den ATARI ST als CORE auf meinem MISTER.
Peter B. schrieb:> ---------------------> So ein Buch hätte ich mir früher für den Atari ST gewünscht,> ---------------------> Davon gab es zwei verschiedene Bücher , jetzt auch noch mit PDF.
Hast du einen Link (oder zwei)?
Ich hätte noch drei verschiedene:
http://www.zilog.com/docs/z80/um0080.pdf
Z80 Assembly Language Subroutines (1983)(Osborne)(pdf)
(in die Suchmaschine eingeben)
und
https://baltazarstudios.com/arduino-zilog-z80/
Grundsätzlich ist es aber ratsam, eher in 8-Bit-Dimensionen zu denken.
Man muss ja u.a. auch klären,
a) welche Reihenfolge, b) welches Datenformat und c) in welcher Richtung
in den Speicher geschrieben wird.
Von der Programmierung her ist es ratsam, sich kleine Module
herzustellen, wie z.B. "wiederhole xy z mal" "schreibe 42" usw. und das
dann aufrufen und loopen bzw. loopunrolling mit machen.
Ich habe jetzt mal Module gemacht.
Wieviel Byte kann man eigentlich mit dem Call nach vorne gehen?
Und wieviel Byte wieder zurück springen mit dem JP?
Es sollten mehr Byte wie 128 sein beim Rücksprung.
----------------------
procedure plotlayer();
begin
asm("
L2_BANK equ 32
call banki
weiter:
call plot
weiter1:
call fertig
banki:
ld bc,#243b
ld a,$56
out (c),a
ld bc,#253b
ld a,L2_BANK*2
out (c),a
jp weiter
plot:
ld hl,$c000+16
ld b,10
loop2:
push bc
push hl
ld b,16
loop1:
ld a,252
ld (hl),a
inc hl
djnz loop1
pop hl
ld bc,256
add hl,bc
pop bc
djnz loop2
jp weiter1
fertig:
ld bc,#243b
ld a,$12
out (c),a
ld bc,#253b
ld a,L2_BANK
out (c),a
ld bc,#243b
ld a,$69
out (c),a
ld bc,#253b
ld a,$80
out (c),a
");
end;
-------------------------
Peter B. schrieb:> Wieviel Byte kann man eigentlich mit dem Call nach vorne gehen?> Und wieviel Byte wieder zurück springen mit dem JP?
Unbegrenzt in beide Richtungen. Die 8080 Befehle adressieren absolut
alle 64 KB. Erst Z80 JR ist PC-relativ.
rbx schrieb:> Ich hatte mehrere Treffer, mit ziemlich ähnlichem Inhalt. Ich würde den> Link vom cpcwiki empfehlen.
Warum tust Du es dann nicht? Verlässt Du Dich darauf, dass auch diesen
link ein anderer für Dich heraussucht, wie es oben schon geklappt hat?
Peter B. schrieb:> Ich habe jetzt mal Module gemacht.> Wieviel Byte kann man eigentlich mit dem Call nach vorne gehen?> Und wieviel Byte wieder zurück springen mit dem JP?> Es sollten mehr Byte wie 128 sein beim Rücksprung.
Die Antwort ist erst mal richtig.
Aber Obacht bei DJNZ und co., da gibt es eine Begrenzung.
Aber die grundsätzliche Frage bleibt, warum willst du in einem Spectrum
rumprogrammieren, wenn du kaum Ahnung vom Z-80 hast?
Zudem es die modernste Form ist.
Der Spectrum ist auch ein Exot in Hard- wie auch Software.
Peter B. schrieb:> Das ist Turbo Rascal.
Und warum geht das nicht in deinem Pascal`
Eigentlich könntest du gleich alles in Assembler machen.
Peter B. schrieb:> ----------------------------------> Willst Du wirklich über 64k verteilt immer die ersten 16 Byte jeder> 256-Byte-Page mit $03 überschreiben ?> ---------------------------------->> Nein die Werte werden sich später ändern , die dann von einem Speicher> ausgelesen werden.
Dann hample nicht mit den Registern rum.
Sondern lade HL, DE, BC mit Werten und dann wie genannt LDIR.
Natürlich vorher einen Bereich befüllen.
Willst du wirklich eine Antwort auf all deine "Schleifen"?
Sei froh, wenn dir paar alte Säcke darauf überhaupt antworten können.
------------------------
Sei froh, wenn dir paar alte Säcke darauf überhaupt antworten können.
------------------------
Ich habe auch erst mit 72 jahren damit angefangen.
In 6 Monaten werde ich 74.
Dein Satz geht daneben.
Nimm du alter Sackmal ein billiges Bandmas , die meisten sind glaube ich
2 Meter.
Schneide davon die Lebenserwartung von einem Man ab. Die Beträgt ca. 87
jahre
Schau dir diese Länge an von 87 cm.
Davon schneidest du dein Lebensalter ab , den Rest davon hälst du in die
Hand....Manche können die wenigen Jahre nicht genießen.
Sei froh wenn du es noch kannst.
Prost
Peter B. schrieb:> Das ist Turbo Rascal.
Wenn Du schon einen Compiler hast, warum willst Du Dich dann mit
Assembler quälen?
Der Compiler macht für Dich die ganze Variablenverwaltung, d.h. Du
kannst soviele Zählschleifen basteln, wie Du RAM hast.
Warum sagst du nicht gleich, worum es eigentlich geht?
Sondern um eine Bankumschaltung und Befüllung mit Bytes bei diesem
neuartigen Spectrum.
https://manuferhi.com/p/n-go-board
Peter D. schrieb:> Wenn Du schon einen Compiler hast, warum willst Du Dich dann mit> Assembler quälen?
Man braucht eigentlich nur noch einen Hexeditor heranziehen, um diesen
ganzen unnötigen Quatsch aus dem Programm wieder rauszuknipsen, den
diese Hochsprachen sonst noch mitbringen und das Programm unnötig
aufblähen.
Natürlich ist das Spaß, möglichst viel Platz zu sparen, und/oder andere
coole Sachen dabei zu lernen auch irgendwie gestrig.