Le X. schrieb:> Die Vorteile deiner Sprache und CPU wären glaubwürdiger wenn wenigstens> der Erfinder sie benutzen würde.
... und zwar für den Webzugang zum Forum. ;-)
A. K. schrieb:> Le X. schrieb:> Die Vorteile deiner Sprache und CPU wären glaubwürdiger wenn wenigstens> der Erfinder sie benutzen würde.>> ... und zwar für den Webzugang zum Forum. ;-)
Sein "Game of Life", was ja als Demo gedacht ist, würde für den Anfang
schon reichen ;-)
Josef G. schrieb:> Die Kritik am Emulationsprogramm wäre glaubwürdiger,> wenn sie von jemandem käme, der es getestet hat.
Die Qualität von Software kann man nicht nur erst zur Laufzeit
beurteilen, sondern auch statisch an dessen Quellcode.
Und die Qualität des Quellcodes ist sehr sehr schlecht, weil er kaum
lesbar, kaum kommentiert und kaum nachvollziehbar dokumentiert ist.
Le X. schrieb:> Sein "Game of Life", was ja als Demo gedacht ist, würde für den Anfang> schon reichen ;-)
Genauso lesbar, aber kürzer: ↑1 ⍵∨.∧3 4=+/,¯1 0 1∘.⊖¯1 0 1∘.⌽⊂⍵
Le X. schrieb:> Sein "Game of Life", was ja als Demo gedacht ist,> würde für den Anfang schon reichen
Ist ja im Maschinencode der CPU geschrieben.
Nicht in der Hochsprache, die ist nicht dafür gemacht,
sondern dafür, fertige Maschinen-Routinen aufzurufen.
Aber die anderen Beispiel-Programme
sind in der Hochsprache geschrieben.
Bernhard K. schrieb:> Oder Forth:
Das wäre dann die Krankheit auf der Krankheit...
Und da Forth -- das sollte die 4. Generation der Programmiersprachen
werden - auf so eine Schnapsidee kann eigentlich nur ein halbes
Bataillon "Software-Evangelisten" kommen, aber das hat ein Physiker
allein erfunden -- massiv mit Unterprogrammaufrufen arbeitet, würden
Josef die fehlenden Call- und Return-Befehle nebst nicht vorhandenem
Stack ganz schön auf die Füße fallen.
Uhu U. schrieb:> Und da Forth -- das sollte die 4. Generation der Programmiersprachen> werden - auf so eine Schnapsidee kann eigentlich nur ein halbes> Bataillon "Software-Evangelisten" kommen, aber das hat ein Physiker> allein erfunden -- massiv mit Unterprogrammaufrufen arbeitet, würden> Josef die fehlenden Call- und Return-Befehle nebst nicht vorhandenem> Stack ganz schön auf die Füße fallen.
Für die klassische FORTH Implementierung als Sequenz von Adressen sind
Unterprogrammaufrufe in der implementierenden Maschinensprache nicht
wesentlich.
Weshalb FORTH beispielsweise zu den eher wenigen Sprachen zählte, die
sich als leidlich effiziente Hochsprache für RCAs 1802 anboten - der
hatte nämlich auch kein CALL/RET, aber genug Adressregister für
indirekte Adressierung zur Implementierung von Stacks.
A. K. schrieb:> Andreas S. schrieb:>> Die von Josef für das von Dir zitierte Beispiel gewählte>> tabellenähnliche Form halte ich im konkreten Fall sogar für sehr>> übersichtlich, da die Art und Weise der Befehldekodierung ersichtlich>> wird.>> Die Übersichtlichkeit leidet eher darunter, dass es zum "Finde den> Unterschied!" wird. Die Variablen sind sich optisch zu ähnlich.
Die Aussage bezieht sich offenbar vor allem auf ccvs und ccvz hier:
1
t1oup <= (s7 and s6 and z5 and z4 and z3 and z2 and z1 and z0 and ccvs) or
2
t1our <= (s7 and s6 and z5 and z4 and z3 and z2 and z1 and z0 and ccvz) or
Und da ist die Ähnlichkeit beabsichtigt. cc.. sind die Bedingungen,
vs steht für V ist gesetzt, vz steht für V ist zero.
Hallo,
Josef G. schrieb:> cc.. sind die Bedingungen,> vs steht für V ist gesetzt, vz steht für V ist zero.
logisch... Warum nicht gleich vg für gesetzt und vu für ungesetzt?
Oder vs für gesetzt und vl für gelöscht?
Oder vo für One und vz für Zero?
Nicht das Du auf die Idee kommst, wie es andere vermutlich täten,
und vs für set und vc für clear nimmst...
Kopfschüttel...
Gruß aus Berlin
Michael
Michael U. schrieb:> Nicht das Du auf die Idee kommst, wie es andere vermutlich täten,> und vs für set und vc für clear nimmst...
Bei Registern wie dem Akku ist die Bezeichnung z üblich.
Ich habe das auch für die Flags übernommen. Dadurch sind
die Bezeichnungen für Flags und Register einheitlich:
z= zero, s= not zero ("set").
Josef G. schrieb:> Bei Registern wie dem Akku ist die Bezeichnung z üblich.
Da hat Josef ausnahmsweise mal recht. :)
Die Bezeichnungen sind in Ordnung und auch Wiederholungen sind in einer
Hardwarebeschreibungssprache bis zu einem gewissen Maße normal.
Nicht in Ordnung sind natürlich die fehlenden Kommentare.
Ein kurzer Kommentar, was V, U, ... sind, wäre hilfreich.
Was V,U,A,K ist, steht zwar nicht als Kommentar im vhdl-Code,
da muss man die Wertzuweisungen an ccvs,ccus,ccas,ccks ansehen.
Aber es steht im Artikel zum Projekt: 8bit-Computer: bo8h
V ist der Carry, U ist Kurzbezeichnung für das Vorzeichenbit A7,
A ist der Akku, K ist Kurzbezeichnung für das Doppelregister AB.
Josef G. schrieb:> V ist der Carry, U ist Kurzbezeichnung für das Vorzeichenbit A7,> A ist der Akku, K ist Kurzbezeichnung für das Doppelregister AB.
V wie Vebertrag und U wie Uorzeichen.
Eigentlich ganz klar ;-)
Josef G. schrieb:> Was V,U,A,K ist, steht zwar nicht als Kommentar im vhdl-Code,> da muss man...
Genau. Irgendwo hast du tatsächlich immer beschrieben, wie alles heißt
und was alles bedeutet.
Aber ist ist leider nur selten klar, wie die Zusammenhänge sind.
Es reicht nicht einfach irgendwo an einer Stelle etwas einmal in einem
Textdokument zu definieren. Die Zusammenhänge mit dem Quellcode fehlen
komplett.
Carl D. schrieb:> Eigentlich ganz klar ;-)
Wurde alles schon ausgiebig diskutiert, hier in diesem Thread
oder im Thread "8bit-Computing mit FPGA".
Der Grund für die Wahl U und V war für mich die optische
Verwandtschaft von U und V. Dadurch sind die Flags U und V
klar von den Mehr-Bit-Registern zu unterscheiden.
Josef G. schrieb:> Carl D. schrieb:>> Eigentlich ganz klar ;-)>> Wurde alles schon ausgiebig diskutiert, hier in diesem Thread> oder im Thread "8bit-Computing mit FPGA".>> Der Grund für die Wahl U und V war für mich die optische> Verwandtschaft von U und V. Dadurch sind die Flags U und V> klar von den Mehr-Bit-Registern zu unterscheiden.
Nur wäre es schöner, wenn sich dahinter die Begriffe Uebertrag/Übertrag
und Vorzeichen verbergen würden.
Das Gegenteil davon würde man nicht erwarten.
Obwohl, ...
Carl D. schrieb:> Nur wäre es schöner, wenn sich dahinter die Begriffe> Uebertrag/Übertrag und Vorzeichen verbergen würden.
Bezugnahme auf deutsche Wörter wäre absolut unüblich.
Ich dachte bei V eher an das v in "over", was man mit
dem Carry in Verbindung bringen kann.
Josef G. schrieb:> Carl D. schrieb:>> Nur wäre es schöner, wenn sich dahinter die Begriffe>> Uebertrag/Übertrag und Vorzeichen verbergen würden.>> Bezugnahme auf deutsche Wörter wäre absolut unüblich.>> Ich dachte bei V eher an das v in "over", was man mit> dem Carry in Verbindung bringen kann.
Warum dann nicht C wie Carry und S wie Sign?
Weil's alle anderen so machen?
Josef G. schrieb:> Bezugnahme auf deutsche Wörter wäre absolut unüblich.
Sonst ist dir das doch auch egal. Irgendwo hast du einen Prozess mit dem
Namen "aktiviere" und im Emulator hast du eine Variable "zeit"
Josef G. schrieb:> Ich dachte bei V eher an das v in "over", was man mit> dem Carry in Verbindung bringen kann.
Und ich dachte immer O(V)erflow (=Überlauf) und (C)arry (=Übertrag)
wären zwei unterschiedliche Flags!
Thomas E. schrieb:> dachte immer O(V)erflow (=Überlauf) und (C)arry (=Übertrag)> wären zwei unterschiedliche Flags!
Da es bei mir kein Overflow-Flag gibt, besteht auch
keine Verwechselungsgefahr, und der Buchstabe V ist
für den Carry verfügbar.
Zum fehlenden Overflow-Flag siehe
Beitrag "Re: Befehlssatz der bo8-CPU - was ist gut, was ist schlecht"
War nicht die Ursprungsfrage: "was ist gut, was ist schlecht?"
Irgendwie scheint jede Antwort, die von "Alles, Nichts" abweicht, nicht
gewünscht zu sein. Damit ist dieser Thread hinfällig.
Sagen wir's mal so... Josef hat es geschafft, ein funktionierendes
System zu entwickeln. Dabei hat er so ziemlich jede existierende
Grundlage ignoriert, sowohl in der Entwicklung als auch in der Benutzung
dieses Systems.
Alles, was man von vergleichbaren Systemen hätte lernen können, ist
hinfällig; alles, was man von bo8 lernen könnte, ist in der Realität
irrelevant, da sowohl Josef als auch bo8 absichtlich mit existierenden
Konventionen brechen.
Der Nutzen ist vergleichbar mit einer Fremdsprache, die nur von einer
einzigen Person - ihrem Erfinder - gesprochen und verstanden wird und in
Struktur und Vokabular von allen existierenden Sprachen abweicht.
Warum sollte man sich damit tiefer beschäftigen?
Josef G. schrieb:> Als Spielerei?
Genau das ist ja die Frage... all das, was ich aus der bo8 lernen
könnte, ist aktiv hinderlich für ein nützliches, detailliertes
Verständnis von Computern. Und das sehe ich als das absolute
Hauptproblem.
S. R. schrieb:>> Als Spielerei?>> Genau das ist ja die Frage... all das, was ich aus der bo8 lernen> könnte, ist aktiv hinderlich für ein nützliches, detailliertes> Verständnis von Computern.
Was hast du an "Spielerei" nicht verstanden?
Ich fände bo8 ganz nett, wenn es ordentlich dokumentiert und
implementiert wäre.
Uhu U. schrieb:> Und da Forth -...- massiv mit Unterprogrammaufrufen arbeitet, würden> Josef die fehlenden Call- und Return-Befehle nebst nicht vorhandenem> Stack ganz schön auf die Füße fallen.
Der Sprungbefehl J.. übergibt aber die Rückkehradresse, und zwar
gleichzeitig im erweiterten Akku K und im Spezialregister Q.
Und jedes der Adressregister X,Y,Z eignet sich auch als Stackpointer.
Nur das Auto-Inkrement/Dekrement beim Laden/Speichern fehlt, das
muss man explizit ausführen.
S. R. schrieb:> Genau das ist ja die Frage... all das, was ich aus der bo8 lernen> könnte, ist aktiv hinderlich für ein nützliches, detailliertes> Verständnis von Computern. Und das sehe ich als das absolute> Hauptproblem.
Vielleicht sollte man das eher im Stil des "Obfuscating C Contest"
betrachten. Dort geht es ja auch darum, möglichst unleserlichen
Programmcode zu entwerfen, der aber strikt standardkonform ist. Als
normaler dilletantischer Programmierer hat man aber kaum eine Chance,
dort einen Blumentopf zu gewinnen.
Weder Josefs VHDL- noch C-Quellcode sind hinreichend unleserlich. Aber
seine gesamte CPU inklusive der Umgebung könnte bei einem "Obfuscating
CPU Contest" einen der vorderen Plätze belegen, und zwar in der Rubrik
"Unverständlichstes Gesamtkunstwerk".
Weil's hier noch nicht angesprochen wurde ...
Der Befehl ADR nn (K erhält K+P+nn+3) "addiere relativ"
für Zugriff auf im Code enthaltene Tabellen
Beispiel: indizierter relativer Sprung. Der Index stehe im Akku.
1
SL.K speichere A in LowByte von K (d.h. in B, A wird 0)
2
TK1 drehe K um 1 Bitstelle, d.h. Multiplikation mit 2
Ma W. schrieb:> Ein relativer Sprung,
Nicht nur, sondern vorher die Auswahl
des Sprungzieles anhand eines Index.
Ein einfacher relativer Sprung würde so gehen:
Robert L. schrieb:> wo liegt der Vorteil gegenüber der üblichen Vorgehensweise?
Mit "übliche Vorgehensweise" meinst du vermutlich so etwas:
jump absolut nnnn, jump relativ nnnn, jump indirekt,
call absolut nnnn, call relativ nnnn, call indirekt, return
wobei noch zu klären wäre, wie "indirekt" genau realisiert ist.
Bei mir gibt es nur den Befehl J.. für alles. Das spart
jedenfalls OpCodes, und es vereinfacht die gleichzeitige
Ausführung einer Memory-Page-Umschaltung. Letzteres war
für mich der Hauptgrund für nur einen J.. -Befehl.
Bei mir dauert ein relativer Sprung (GTR nn / AD. nn / J..)
nicht länger als ein absoluter Sprung (GTA nn / AD. nn / J..),
das erspart dem Programmierer den Konflikt der Entscheidung
zwischen Komfort und Geschwindigkeit.
Das Sprungziel bei J.. steht im erweiterten Akku K, die Berechnung
des Ziels bei indirektem Sprung kann also beliebig komplex sein.
Alle Speicherzugriffe sind 8-Bit-Zugriffe, man braucht keine
16-Bit-Zugriffe wie bei jump nnnn. Das ist zwar kein Vorteil
für den Programmierer, aber es vereinfacht den Aufbau der CPU.
Meine Lösung hat natürlich auch Nachteile. Der einfache
absolute Sprung dauert länger, belegt mehr Speicherplatz
und überschreibt den Akku.
Josef G. schrieb:> Bei mir dauert ein relativer Sprung (GTR nn / AD. nn / J..)> nicht länger als ein absoluter Sprung (GTA nn / AD. nn / J..),> das erspart dem Programmierer den Konflikt der Entscheidung> zwischen Komfort und Geschwindigkeit.
Es erspart dem Programmierer die Entscheidung, weil der relative Sprung
keinen Vorteil gegenüber dem absoluten Sprung hat?
Warum gibts ihn dann überhaupt?
Josef G. schrieb:> das erspart dem Programmierer den Konflikt der Entscheidung> zwischen Komfort und Geschwindigkeit.
Was für ein irrwitziges Argument für ein Prozessordesign...
> Das ist zwar kein Vorteil für den Programmierer, aber es vereinfacht> den Aufbau der CPU.
Solche Überlegungen hatten in der Anfangszeit Computerentwicklung ihre
Berechtigung, als ein einzelner Transistor noch richtig Geld kostete.
So ein Design auf einem FPGA zu impementieren, ist völliger Schwachsinn,
der bei einem Hobby-Bastler gerade noch angehen mag. Er sollte sich
dabei aber immer vor Augen halten, dass er damit das Rad neu erfindet
und das keine Leistung ist, auf die ein halbwegs rational denkender
Mesch sich was einbilden kann.
Ma W. schrieb:> weil der relative Sprung> keinen Vorteil gegenüber dem absoluten Sprung hat?
Der relative Sprung hat nicht den Nachteil einer längeren Laufzeit.
(Ich meinte hier einen Sprung mit langer Adressierung. Relative
Sprünge mit kurzer Adressierung können natürlich schneller sein.)
> Warum gibts ihn dann überhaupt?
Um verschiebbare Programme zu schreiben.
Ma W. schrieb:> Josef G. schrieb:>> Um verschiebbare Programme zu schreiben.>> Der Assembler mit Labelnamen wurde auch bereits erfunden.
Ja, hat auch mein Assembler.
Ändert aber nichts daran, dass man fertige Programme
mit absoluten Sprüngen innerhalb des Programms
nicht ohne Modifikation verschieben kann.
S. R. schrieb:> Der Begriff "Position Independent Code" sagt dir nix, oder?
Natürlich weiß ich, was das ist.
Wozu braucht eine bo8-CPU das noch gleich?
Ma W. schrieb:>> Der Begriff "Position Independent Code" sagt dir nix, oder?> Natürlich weiß ich, was das ist.
Warum regst du dich dann darüber auf, dass es relative Sprünge gibt?
Der Z80 hat die auch eingebaut, weil sie beim i8080 fehlten, aber
praktisch sind.
> Wozu braucht eine bo8-CPU das noch gleich?
Spielt keine Rolle. Sie kann es und gibt dir die Freiheit, es zu nutzen.
Nutzen tust du es genau da, wo du es auch auf einem Mikrocomputer nutzen
würdest, wenn du könntest... für einen Debugger zum Beispiel.
Man kann ja viel an dem Projekt kritisieren, aber die Existenz eines
durchaus sinnvollen Features zähle ich jetzt mal nicht dazu...
S. R. schrieb:> Der Z80 hat die auch eingebaut,
Wobei das nur Sprünge im Nahbereich -126 .. +129 sind.
Entspricht meinen O... und B... -Befehlen,
die aber eine zweimal so große Maximaldistanz haben.
Relative Sprünge oder auch Calls mit größerer Distanz
gibt es beim Z80 nicht, wenn ich das richtig sehe.
Und das wird durchaus vermisst:
http://www.vcfed.org/forum/showthread.php?54821-Z80-relative-CALL
Bei mir gibt es die Befehle GTR nn und ADR nn
zum Laden oder Addieren einer PC-relativen Adresse
im Nahbereich. In Kombination mit einem nachfolgenden
AD. nn entfällt die Beschränkung auf den Nahbereich.
Und die erhaltene relative Adresse kann nicht nur
als Ziel für Jump oder Call verwendet werden, sondern
auch als Adresse einer im Code mitgeführten Tabelle.
Josef G. schrieb:> Bei mir gibt es die Befehle GTR nn und ADR nn> zum Laden oder Addieren einer PC-relativen Adresse> im Nahbereich. In Kombination mit einem nachfolgenden> AD. nn entfällt die Beschränkung auf den Nahbereich.>> Und die erhaltene relative Adresse kann nicht nur> als Ziel für Jump oder Call verwendet werden, sondern> auch als Adresse einer im Code mitgeführten Tabelle.
PC lesen, etwas aufaddieren und dann indirekt darauf zu springen ist
kein klassischer relativer Sprung. Das ist ein indirekter Sprung.
Natürlich kann ein indirekter Sprung auch relativ zu PC sein, wenn man
PC lädt und etwas addiert.
"Richtige" relative Sprünge haben das relative jumptarget immediate
einfach als Operand.
Ma W. schrieb:> PC lesen, etwas aufaddieren und dann indirekt darauf zu springen ist> kein klassischer relativer Sprung. Das ist ein indirekter Sprung.
Ja, schon richtig. So gesehen sind bei mir alle langen Sprünge
indirekte Sprünge. Bei mir kann man halt im Gegensatz zum Z80
den PC sehr einfach und ohne Tricks lesen, das wollte ich sagen.
Josef G. schrieb:> Relative Sprünge oder auch Calls mit größerer Distanz> gibt es beim Z80 nicht, wenn ich das richtig sehe.
Relative Sprünge gibt es auf dem Z80 nur aus Gründen der
Speicherersparnis. Die Assemler konnten verschiebliche Module erzeugen
und Linker konnten sie auf jede dafür geeignete Adresse relokieren - man
war damals einfach schon viel weiter, als du heute...
Ma W. schrieb:>> PC lesen, etwas aufaddieren und dann indirekt darauf zu springen ist> kein klassischer relativer Sprung. Das ist ein indirekter Sprung.
Wovon auch immer du redest. Den PC lesen, etwas drauf addieren und dann
dahin zu springen ist ein relativer Sprung. Wo du oben die Indirektion
her holst, ist mir schleierhaft.
> Natürlich kann ein indirekter Sprung auch relativ zu PC sein, wenn man> PC lädt und etwas addiert.
Ein indirekter Sprung ist ein indirekter Sprung. Das Kennzeichen einer
indirekten Operation ist, daß der Operand nicht das Ziel ist, sondern
daß der Operand angibt, wo das Ziel gespeichert ist. Beim Z80 wäre
1
JMP (HL)
etwa ein indirekter Sprung. Der Operand ist das HL-Register und dieses
Register enthält das Ziel des Sprungs.
> "Richtige" relative Sprünge haben das relative jumptarget immediate> einfach als Operand.
Irgendwie schmeißt du hier indirekt und relativ durcheinander.
Relativ ist immer in Bezug auf eine Basisadresse. Bei Sprüngen wäre der
momentane PC diese Basisadresse und der Operand ist der Offset. Indirekt
habe ich oben erklärt. Kombinationen gibt es durchaus auch, einerseits
mit dem Offset innerhalb der Indirektion, z.B.
1
LDA (xx,X)
oder außerhalb der Klammer, z.B.
1
LDA (xx)+Y
(jeweils aus dem instruction set des 6502)
Die Adresssierungsart nennt man dann /relativ, indirekt/ oder /indirekt,
relativ/. Beim Z80 gibt es diese Varianten z.B. unter Verwendung der IX
bzw. IY Register. Bei Sprüngen wäre mir diese Kombination aus
Relativität und Indirektion aber neu. Was nicht ausschließt, daß es eine
esoterische Architektur gibt, die genau das hat ;)
PC-relative Adressierung von Code und Daten fiel nicht fertig vom
Himmel, die entwickelte sich. Bei 8-Bittern wie Z80 oder 6502 ergab das
nur bei Code wirklich Sinn, ebenso bei 16-Bittern wie 8086. Bei Z8000
und 68000 konnte man immerhin schon Daten PC-relativ laden, aber nicht
speichern - dachte man doch, dass PC-relative Adressierung von Daten nur
in Form von Loads sinnvoll sei, da wäre sowieso bloss ROM in der Nähe.
Bei 32-Bit Adressräumen und Betriebssystemen merkte man dann, dass es
eine feine Sache sein kann, nicht nur Code PC-relativ adressieren zu
können, sondern auch Daten. Um positionsabhängigen Code erzeugen zu
können. Aber x86 kann erst seit amd64 Daten PC-relativ adressieren.
Compiler können zwar Code erzeugen, der das trotzdem tut, aber die
Effizienz leidet darunter.
Axel S. schrieb:> Wo du oben die Indirektion> her holst, ist mir schleierhaft.
Dann lies nochmal, was Josef macht.
Es ist ein ganz normaler indirekter Sprung.
Seine CPU hat keine Instruktion für relative Sprünge.
Axel S. schrieb:> Was nicht ausschließt, daß es eine> esoterische Architektur gibt, die genau das hat ;)
So arg esoterisch war das früher nicht. Bis in die 70er konnten einige
Architekturen recht konsequent indirekt über Speicherworte adressieren.
Die im Befehl berechnete Adresse war dann also wahlweise die Adresse
selbst - 6502: n,X - oder die Adresse der Zieladresse - (n,X).
Beispielsweise die recht beliebte 12-Bit PDP-8, die innerhalb der
aktuellen Program-Page indirekt über Speicher adressieren konnte. Die
vom gleichen Designer entwickelten 16-Bit "Nova" Minicomputer von Data
General hatten eine RISC-ähnliche Codierung in einem einzigen 16-Bit
Word und konnten daher keine vollständige Adresse im Befehl codieren.
Statt dessen gab es eine 8-Bit Distanz zu 0, dem PC, oder zu 2
Registern. Und das dann wählbar indirekt wie (n,X) bei 6502. Absolute
Adressierung von dadurch nicht direkt erreichbarem Code und Daten
verwendete also ein relativ zum PC erreichtes Adresswort im Speicher,
vergleichbar zur verbreiteten Methode bei 32-Bit ARM (dort mit 2
Befehlen).
NB: Der billige 8-Bit Mikroprozessor SC/MP von National Semiconductor
(von Elektor Ende 70er verwendet) wiederum adressierte alles mit 8-Bit
Distanz zu irgendwas (PC oder 3 Register), aber ohne diese Form der
Indirektion über den Speicher. Es gab also auch bei Sprungbefehlen nur
diese relativen Adressierungen, keine Sprungbefehle reichten weiter als
diese 8-Bit Distanz. Zusätzlich gab es nur noch "Exchange PC mit
Register". Ziemlich gruselig, zumal es auch keinen CALL Befehl gab.
Axel S. schrieb:> Beim Z80 wäre JMP (HL) etwa ein indirekter Sprung.> Der Operand ist das HL-Register und dieses Register> enthält das Ziel des Sprungs.
Kleine Frage am Rande: Die Notation JP (HL) erscheint mir
unlogisch. Müsste es nicht eigentlich JP HL heissen? Denn
in den PC wird HL geladen, und nicht die zwei Bytes
im Speicher, auf welche HL zeigt.
Josef G. schrieb:> Die Notation JP (HL) erscheint mir> unlogisch. Müsste es nicht eigentlich JP HL heissen?
Denkweise: Es wird an die Stelle gesprungen, auf die HL zeigt. Es wird
nicht auf HL gesprungen.
Josef G. schrieb:> Kleine Frage am Rande: Die Notation JP (HL) erscheint mir> unlogisch. Müsste es nicht eigentlich JP HL heissen? Denn> in den PC wird HL geladen, und nicht die zwei Bytes> im Speicher, auf welche HL zeigt.
Jein. Ohne Klammern würde der Befehl bedeuten, dass der PC auf die
Adresse von HL gesetzt wird. Allerdings sind beim Z80 die Register gar
nicht im Programm-Adressraum enthalten, so dass eine Unterscheidung
nicht nötig wäre. Bei Prozessoren mit im Adressraum befindlichen
Registersatz wäre es hingegen mehrdeutig.
Niemand, der das Emulationsprogramm und Game of Life
ausprobieren will? Die Bilder sehen wirklich gut aus ...
Beitrag "Re: 8bit-Computing mit FPGA"Josef G. schrieb:> Die Beschreibung dazu steht auf der Seite Emul.txt> am Ende der Beschreibung des Emulationsprogramms.>> Man braucht dazu auch die Datei teca im aktuellen Verzeichnis.>> Zur Eingabe des Kommandos 1.GOL drückt man 1^gol und dann Return.>> Zuvor wechselt man mit shift-e in die Seite E und erstellt dort> im Bereich der ersten 64 Zeilen ein wenig Text. Zum angenehmeren> Arbeiten schiebt man mit shift-v Text und Cursor ein paar Zeilen> nach unten. Der Text dient als Startbild. Mit shift-e kehrt man> in die Seite C zurück und gibt dort das Kommando ein.>> Nach Eingabe-Aufforderung SIZE drückt man 0 oder 1,> nach Eingabe-Aufforderung RULE drückt man 0.> Iterationen führt man aus mit Taste ^.
@ Josef G. (bome) Benutzerseite
>Niemand, der das Emulationsprogramm und Game of Life>ausprobieren will?
Keiner? Wirklich keiner? OMG!
> Die Bilder sehen wirklich gut aus ...
"The beauty lies in the eye of the beerholder" ;-)
Josef G. schrieb:> Niemand, der das Emulationsprogramm und Game of Life> ausprobieren will?
Wie soll ich das denn tun?
Nach dem Herunterladen des Pakets ist es gar nicht möglich
herauszufinden, was die einzelnen Dateien tun und wie man sie verwendet.
Das Verzeichnis mit der "Dokumentation" enthält zwar viel Text, aber es
ist nicht möglich einen Einstiegspunkt oder gar einen Zusammenhang zu
erkennen.
Wie baue ich das Paket? Wo ist die Makefile oder ein ähnliches
build-script?
Welche Voraussetzungen werden an mein System gestellt?
Was muss ich ausführen?
>Die Bilder sehen wirklich gut aus
Man findet nirgendwo eine Erklärung, was denn dort genau zu sehen ist.
Nein "Ein Demo-Programm" und "Conway's Game of Life 128*128" ist nicht
ausreichend.
Ma W. schrieb:> Wie soll ich das denn tun?
Steht alles in der Datei Emul.txt im Verzeichnis info.
Nicht vergessen: bei coka.txt und teca.txt das .txt entfernen.
> Wo ist die Makefile oder ein ähnliches build-script?
Gibt es nicht, braucht man nicht.
Wie man emul.c compiliert, steht in Emul.txt.
> Welche Voraussetzungen werden an mein System gestellt?
Beliebiges Linux mit X-Grafik.
Josef G. schrieb:>> Wie soll ich das denn tun?>> Steht alles in der Datei Emul.txt im Verzeichnis info.
Achso.
Normalerweise gibt es eine Datei namens README. Das ist seit gefühlt 100
Jahren der de-facto Standard für den Einstieg in eine Dokumentation.
Vielleicht solltest du eine solche Datei anlegen, in der du einen
Überblick über das Projekt beschreibst und auf die weitere Doku
verlinkst.
Tipp: In einem Überblick kommen keine Registernamen oder so etwas vor.
Es wird in verständlicher und größtenteils nichttechnischer Sprache
beschrieben, was das Projekt ist und was ich damit machen kann.
>> Wo ist die Makefile oder ein ähnliches build-script?>> Gibt es nicht, braucht man nicht.
Doch, das braucht man.
Niemand hat Lust sich irgendwelche Kommandos aus der Doku zu frickeln.
Es gibt Standardtools zum Bau von Projekten. Eines wäre z.B. make.
Wenn ein Projekt eine Datei namens "Makefile" hat, weiß direkt jeder,
was zu tun ist. Und das ganz ohne Doku.
> Wie man emul.c compiliert, steht in Emul.txt.>>> Welche Voraussetzungen werden an mein System gestellt?>> Beliebiges Linux mit X-Grafik.
Achso. Na gut. Ich vermute, dass man noch irgendwelche dev-Pakete
installieren muss?
# Starten Sie es aus einem Konsolenfenster mit ./emul #
7
# #
8
# Bei geöffnetem Grafikfenster nicht klicken, auch nicht #
9
# auf den Schließen-Knopf in der Kopfleiste des Fensters. #
10
# Gefahr von FATAL ERROR. Grafik beenden mit shift-q. #
11
# #
12
# Nur für Notfälle ist anstelle des Beendens mit shift-q #
13
# das Beenden durch Klick IM INNEREN des Grafikfensters #
14
# vorgesehen. Aber vermutlich funktioniert das nur dann, #
15
# wenn ohnehin auch das Beenden mit shift-q funktioniert. #
16
# Und es ist nur unzureichend getestet. #
17
...
Irgendwie bekomme ich Angst, wenn ich das lese. Es gibt die Gefahr eines
FATAL ERRORs. Was auch immer das ist.
Löscht das Progamm zufällig auch meine Festplatte, wenn ich die falsche
Taste drücke? Nachprüfen kann ich das ja nicht, weil der Sourcecode
nicht lesbar ist.
Ma W. schrieb:> dass man noch irgendwelche dev-Pakete installieren muss?
C-Compiler. Dürfte jeder technische Anwender ohnehin haben.
> Irgendwie bekomme ich Angst, wenn ich das lese.
Ok, das kann ich nicht entkräften.
Muss jeder selber wissen, ob er es riskieren will.
Josef G. schrieb:>> dass man noch irgendwelche dev-Pakete installieren muss?>> C-Compiler. Dürfte jeder technische Anwender ohnehin haben.
Und X11 dev-Pakete?
Sonstige?
>> Irgendwie bekomme ich Angst, wenn ich das lese.>> Ok, das kann ich nicht entkräften.> Muss jeder selber wissen, ob er es riskieren will.
Ok. Das weckt jetzt wirklich Misstrauen in dich und dein Projekt.
Es ist ja schon fast fahrlässig, das außerhalb einer virtuellen Maschine
zu betreiben, meinst du nicht?
Josef G. schrieb:>> Und warum gibt es kein Makefile?> Weil ich keine Ahnung habe, wie man so etwas schreibt.
Das ist trivial zu erlernen und zu schreiben.
Und es erleichtert deinen Nutzern das Leben ganz enorm. Und dir übrigens
auch. Du weißt es nur noch nicht.
Josef G. schrieb:> Alexander F. schrieb:>> Und warum gibt es kein Makefile?>> Weil ich keine Ahnung habe, wie man so etwas schreibt.
Au weia...
Und dann beklagst du dich, warum sich niemand mit ddeinem Zeugs befassen
will? Wie weltfremd ist das denn?
Josef G. schrieb:> Alexander F. schrieb:>> Und warum gibt es kein Makefile?>> Weil ich keine Ahnung habe, wie man so etwas schreibt.
Du scheinst schon Internetzugang zu haben.
Da steht ganz viel Lehrreiches drin, auch über "make" und seine Files.
Mußt nur nachlesen.
Alexander F. schrieb:> Wo kommen denn die Dateien codG, coka, emtext-a usw. her?> Gibt es dafür auch Sourcecode?
coka und teca sind Maschinencode für meine CPU, erstellt mit
Papier und Bleistift. Bisher kein maschinenlesbarer Sourcecode,
Nacherstellung mit Disassembler und händischer Nachbearbeitung
ist angedacht, Vorgehensweise in Ansätzen schon getestet.
codG ist Teil von teca.
emtext-* sind erstellt und lesbar mit Emulationsprogramm.
Josef G. schrieb:> coka und teca sind Maschinencode für meine CPU, erstellt mit> Papier und Bleistift.
Das ist zwar eine große Leistung und ich erkenne diese auch hoch an.
Aber es ist bezeichnend für das Projekt als Ganzes.
Für Außenstehende ist so ein Binärblob leider vollständig unbrauchbar.
Und zu den Binärblobs zähle ich auch die .c und .vhdl Dateien. Weil auch
diese, was die Lesbarkeit angeht, nicht weit von Maschinencode entfernt
sind.
Josef, du hast eine hervorragende kognitive Leistung gebracht und dieses
Projekt aufgezogen. Leider ist es nicht im geringsten praxistauglich.
Es ist unmöglich daraus etwas praktisch brauchbares zu machen, ohne es
komplett neu zu entwickeln.
Das soll dich aber nicht davon abhalten weiter daran zu arbeiten, wenn
das dir Spaß macht. Aber bitte erwarte keine positive Rückmeldung von
außen, oder sogar Mitstreiter. Das wird es niemals geben.
Es gibt übrigens Tools, die dir bei der Codeformatierung helfen können.
Mit dem Programm "indent", was es auf jeder Linux-Distri gibt, kann man
C-Code vernünftigt neuformatieren.
Siehe Dateien im Anhang. Einmal Josef-Original und einmal durch indent
mit folgenden Parametern gejagt:
Das Ergebnis ist schon mal wesentlich besser lesbar.
Es fehlen zwar immer noch vollständig Kommentare und aussagekräftige
Namen, aber das kann ein Tool ja nicht leisten.
emul.c:415:2: warning: this ‘if’ clause does not guard... [-Wmisleading-indentation]
32
if(zei) K=(zei<<8)+(K & 255); zei=0; zeit=0;}}
33
^~
34
emul.c:415:32: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the ‘if’
35
if(zei) K=(zei<<8)+(K & 255); zei=0; zeit=0;}}
36
^~~
Mit Indent:
1
gcc -o emul -Wall -lX11 emul-indent.c
2
emul-indent.c: In function ‘main’:
3
emul-indent.c:966:18: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
4
printf("\nt: %x\n", zeit);
5
~^
6
%lx
Mit eingeschalteter Optimierung zeigen sich aber noch weitere sehr
interessante Warnings:
1
gcc -O2 -o emul -Wall -lX11 emul-indent.c
2
emul-indent.c: In function ‘main’:
3
emul-indent.c:966:18: warning: format ‘%x’ expects argument of type ‘unsigned int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
4
printf("\nt: %x\n", zeit);
5
~^
6
%lx
7
emul-indent.c:148:6: warning: array subscript is above array bounds [-Warray-bounds]
8
sr[65] = 0;
9
~~^~~~
10
emul-indent.c:1183:10: warning: ‘modw’ may be used uninitialized in this function [-Wmaybe-uninitialized]
11
if (modw)
12
^
13
emul-indent.c:1224:15: warning: ‘modn’ may be used uninitialized in this function [-Wmaybe-uninitialized]
14
if (modn == 1 && zei < 0xc8)
15
~~~~~^~~~
16
emul-indent.c:1163:8: warning: ‘modx’ may be used uninitialized in this function [-Wmaybe-uninitialized]
17
if (modx == 2) {
18
^
19
emul-indent.c:1166:6: warning: ‘zeix’ may be used uninitialized in this function [-Wmaybe-uninitialized]
20
printf("hex: %c%c\nhex off\n", zeix, n);
21
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Insbesondere
>warning: array subscript is above array bounds
Du hast dort einen Buffer-Overflow im Code.
Die Warnings über uninitialisierte Variablen habe ich jetzt nicht
genauer untersucht. Die können harmlos sein, oder auf einen Bug
hindeuten.
Und die Warnungen wegen nicht initialisierter Variablen jucken dich
überhaupt nicht?
Jeder halbwegs seriöse Programmierer wird sie als Signal für
unzuverlässigen Code interpretieren.
Uhu U. schrieb:> Und die Warnungen wegen nicht initialisierter Variablen
Nein, nicht uninitialisiert, sondern vielleicht uninitialisiert.
> may be used uninitialized
modx, modn, modw werden erst dann abgefragt, nachdem vorher die Zeile
Josef G. schrieb:> Nur erkennt das offenbar der Compiler nicht, daher die Warnungen.
Und warum entfernst du diese Warnungen nicht ganz einfach trotzdem?
Code, der mit Warnungen compiliert, ist aus mehreren Gründen schlechter
Stil.
Erstens verdecken die unnötigen Warnungen echte Warnungen. Echte
Probleme, wie das mit dem Pufferüberlauf, gehen in der Flut schnell
unter.
Warnungfreier Code zeigt mir, dass der Programmierer sich die Mühe
gemacht hat alle Warnungen zu bewerten und zu beheben. Wenn Warnungen in
Code auftauchen, dann weiß ich nicht, ob du dir darüber Gedanken
gemacht hast.
Idealerweise sollte der Code auch dann keine Warnungen produzieren, wenn
man ihn durch ein etwas genaueres Tool als einen Compiler schickt; so
etwas wie valgrind, lint oder cppcheck kann einem da die Augen öffnen
(und helfen, den eigenen Programmierstil zu verbessern).
Josef G. schrieb:> Nein, nicht uninitialisiert, sondern vielleicht uninitialisiert.
Das heißt auf Deutsch: Es gibt Pfade durch das Programm, die keine eine
Initialisierung der Variablen bewirken.
Deswegen initialisiert man sowas üblicherweise bei der Deklaration -
dann kannst du dir auch die if-Abfrage sparen. Die paar zusätzlichen
Befehle wirst du auf einem PC nicht bemerken, die gehen im Rauschen
unter.
> zeix wird nur dann abgefragt, wenn vorher in der Zeile
Na ja, mit solchen "Optimierungen" schaufelst du deinem Projekt das
Grab, bevor es auch nur ein wenig in Schung kommen kann.
> Nur erkennt das offenbar der Compiler nicht, daher die Warnungen.
Sowas ist datenabhängig. Weißt du denn sicher, dass nicht nur heute,
sondermn auch in aller Zukunft dort nichts auftreten kann, was zue
Auswertung einer uninitialisierten Variablen führen könnte?
Profis machen solchen Scheiß nicht, du hast einen unbändigen Hang, am
falschen Ende zu sparen...
Josef G. schrieb:> Nur erkennt das offenbar der Compiler nicht, daher die Warnungen.
Der benutzte Compiler ist aber sehr gut darin, zu erkennen, daß
irgendwas nicht eindeutig beschrieben wurde. Dann sollte man seine
Anweisungen in diesen Punkten präzisieren.
Zum Thema schlechter Programmierstil:
> sr[64]=0;
Das ist schlechter Programmierstil. Was ist 64? Woher kommt die Zahl?
Warum verwendest Du keine sprechend benannte Konstante für die
Arraygröße und nutzt die bei der Zuweisung (mit -1 als Offset)?
Daß ein Variablenname "sr" ebenfalls komplett nichtssagend ist, muss
nicht weiter erwähnt werden. Du könntest, um das ganze noch etwas
unübersichtlicher zu machen, auch einfach alle Variablen numerieren,
oder alle in einem Array zusammenfassen, und dann sämtliche Variablen
mit Arrayzugriffen wie dem da oben ansprechen.
Das wäre dann noch schlechterer Programmierstil.
Josef G. schrieb:> schau ich mir später an.
Bitte baue deine Programme komplett um, bevor du mit kosmetischen
Änderungen anfängst. Sonst hat das alles keinen Sinn.
Du verwendest, außer main, keine Funktionen, hast aber große Codeteile,
die in allen deinen C-Dateien vorkommen. Du kopierst also jede Änderung
in mehrere Dateien. So schreibt man keine Software.
http://www.c-howto.de/tutorial/funktionen/
Lagere die immer gleichen Teile des Codes in eigene Source- und
Header-Dateien aus. Du hast schon geschrieben, dass du nicht weißt, wie
das funktioniert. Irgendwie hast du es aber geschafft, eine CPU zu
schreiben, also kannst du das auch lernen.
Kommentiere deinen Code. Du hast keine Kommentare in deinem Code.
Niemand will die Dokumentation durchsuchen, nur um herauszufinden was
eine Variable macht. Solche Dinge müssen im Code stehen.
Mein Gott, soviele Leute mit Helfersymdrom und so wenig
Menschenkenntnis? Dem Josef ist nicht zu helfen, nicht mal von
Medizineren und der Pharmaindustrie!
Oder ist es eher die morbide Lust an Skurilitäten?
Ma W. schrieb:> Warnungfreier Code zeigt mir, dass der Programmierer sich die Mühe> gemacht hat alle Warnungen zu bewerten und zu beheben.
Leider lehrt mich die Erfahrung bei manchen Leuten etwas anderes:
warnungsfreier Code zeigt mir, dass der Programmierer sich die Mühe
gemacht hat, die Compileroptionen so zu setzen, dass sie unterdrückt
werden. Und wenn er dafür von anderen Entwicklern eins auf die Finger
bekommen hat, verwendet er eben #pragma-Anweisungen in seinem Quellcode,
um die Unterdrückung von Warnungen dort zu verstecken.
Und ein wirklich drittklassiger Entwickler, dessen paar Zeilen Code zu
über tausend Warnungen führten, behauptete, man müsse einfach nur
zweimal kompilieren, damit die Warnungen verschwindeten. Er wollte nicht
einsehen, dass beim zweiten make überhaupt nicht mehr kompiliert wurde.
Hatte ich schon erwähnt, auf welchen Entwickler des Teams von ca. zehn
Leuten mehr als 90% aller Fehlerberichte von Testern und Anwendern
entfielen?
Josef G. schrieb:> Niemand, der das Emulationsprogramm und Game of Life> ausprobieren will? Die Bilder sehen wirklich gut aus ...> Beitrag "Re: 8bit-Computing mit FPGA">
um sich über das Spiel (und die Regeln) zu informieren ließt man z.B:
http://web.stanford.edu/~cdebs/GameOfLife/
um es zu SPIELEN und sich Sourcecode anzuschauen auch vielleicht hier
http://pmav.eu/stuff/javascript-game-of-life-v3.1.1/
oder das Spiel in ASM:
https://github.com/PyvesB/asm-game-of-life
(und JA mit makefile und Readme..)
https://github.com/Pixinn/gameoflife-appleii/blob/master/src/gol_optimized.asm
usw. usw.
WARUM? sollte man sich DEINER Meinung nach also mit deinem Projekt
beschäftigen?
um dir die Frage zu vereinfachen:
Schau dir den oben verlinkten Sourcecode/Projekte an..
Du wirst dich, ohne dich länger dort einzulesen NICHT zurecht finden (es
gibt Befehle die du nicht kennst, Grundlagen die du nicht hast usw.)
und das OBWOHL der Code Sehr gut dokumentiert ist, es Aussagekräftige
Namen gibt, der code "Strukturiert" ist (soweit das in ASM eben geht)
und erklärt ist welche Grundlagen man braucht um es zum laufen zu
bringen (zentral und nicht in 20 Forenbeiträgen verteilt)
Also nochmal die einfache Frage: WARUM? sollte man sich DEINER Meinung
nach also mit deinem Projekt beschäftigen?
Robert L. schrieb:> Also nochmal die einfache Frage: WARUM? sollte man sich DEINER Meinung> nach also mit deinem Projekt beschäftigen?
Und doch tun es etliche Leute in diesem Thread. Also scheint Josefs
Projekt doch eine gewisses Interesse hervorzurufen. Sonst wäre dieser
Thread nicht 500 Beiträge lang.
Der Quietsch-Rote, Tiefergelegte GolfIII, bei jeder Bodenwelle
aufsetzend, mit Fehlzündungen und Flammen aus dem 40cm Durchmesser
Auspuff..
führt auch zu Diskussionen ÜBER das Auto..
aber nicht dazu dass man in die nächste Garage rennt und beginnt zu
schrauben..
vielleicht ist so klarer wie die Frage gemeint war?
Robert L. schrieb:> aber nicht dazu dass man in die nächste Garage rennt und beginnt zu> schrauben..>> vielleicht ist so klarer wie die Frage gemeint war?
Um bei deinem Vergleich zu bleiben: Es gibt hier etliche Leute, die
regelmäßig zu dem Auto zurück kommen, und mit dem Besitzer die neusten
Veränderungen am Wagen zu Diskutieren. Von daher kann man zumindest
nicht behaupten der Wagen / die CPU hätte kein Interesse geweckt. Wodrin
auch immer dieses Interesse jetzt bestehen mag...
@Da Dieter (dieter)
>Veränderungen am Wagen zu Diskutieren. Von daher kann man zumindest>nicht behaupten der Wagen / die CPU hätte kein Interesse geweckt. Wodrin>auch immer dieses Interesse jetzt bestehen mag...
Pathologen haben auch viele Interessen . . .
Und Psychiologen, Soziologen, Neurologen . . .
Da D. schrieb:> Um bei deinem Vergleich zu bleiben: Es gibt hier etliche Leute, die> regelmäßig zu dem Auto zurück kommen,
nicht Auto sondern Pferdekutsche..
Hallo,
ich würde das Ganze mal in Kunstprojekt umbenennen.
Würde auch diesen und seine vorherigen Threads stark verkürzen, weil
damit alle Fragen zu Nutzen und Anwendung nicht gestellt werden
brauchten.
Gruß aus Berlin
Michael
Rufus Τ. F. schrieb:> Zum Thema schlechter Programmierstil:>>> sr[64]=0;>> Das ist schlechter Programmierstil. Was ist 64? Woher kommt die Zahl?> Warum verwendest Du keine sprechend benannte Konstante für die> Arraygröße und nutzt die bei der Zuweisung (mit -1 als Offset)?>> Daß ein Variablenname "sr" ebenfalls komplett nichtssagend ist, muss> nicht weiter erwähnt werden. Du könntest, um das ganze noch etwas> unübersichtlicher zu machen, auch einfach alle Variablen numerieren,> oder alle in einem Array zusammenfassen, und dann sämtliche Variablen> mit Arrayzugriffen wie dem da oben ansprechen.>> Das wäre dann noch schlechterer Programmierstil.
Das liegt sicher daran, daß das zwar aussieht wie C, aber in
Wirklichkeit b(one) ist. Es gibt kein sizeof und der Compiler selbst
unterscheidet bei Symolen nur 2 Zeichen.
Wenn man "Rechner-Technik" neu erfindet, dann wenigstens konsequent
alles von gaaaannnzzz vorne.