Forum: Mikrocontroller und Digitale Elektronik Retro Fieber: Z80 oder 68000 ?


von Axel S. (a-za-z0-9)


Lesenswert?

Die Schweizer wieder!

von Michael_ (Gast)


Lesenswert?

Axel Schwenke schrieb:
> Christian J. schrieb:
>> Erklär mir mal einer das:
>>
>> Mit so 16-19 schrieb ich hunderte Zeilen Asm locker auf dem Papier
>> runter. Ummrechnungstabelle brauchte ich nicht, kannte die Hex Codes
>> der Mnemonics auswendig.
> ...
>> Aber mit 45 breche ich mir einen ab mit DIESEM SCHEISS ASSEMBLER !!!!
>
> Du bist einfach zu alt. Also nicht physiologisch, sondern geistig.
> Such dir ein anderes Hobby. Blumen züchten. Schnecken dressieren.
> Briefmarken sammeln. Was einfaches halt :P

Glaubst du wirklich, deine Alternativen sind nicht einfach :-)
Und lass ihn doch. Er hat es doch fein hingekriegt mit seiner 
Fädeltechnik.
Nie im Leben würde ich mir das antun. Alle Achtung!
Natürlich muß man fragen, wie sein Zustand mit 60 Jahren ist.
Aber im Grunde hat er Recht. Das genannte TDL-Basic hab ich damals auch 
mit Hand eingetippt. Heute würde ich sowas nicht mehr machen. Die Luft 
ist raus!

von Christian J. (Gast)


Lesenswert?

Georg G. schrieb:
> Ich wiederhole diverse frühere Statements von vielen Leuten aus diesem
> Thread: Nimm einen der vielen Debug Monitore. Dann lädst du dein
> Programm ins RAM und kannst mit Brechpunkten das Ding Stück für Stück
> durchgehen. Den Monitor an deine Hardware anzupassen ist eine Sache von
> 15 Minuten (maximal).

Hallo,

danke für die Antworten. Das hier scheint mir das Sinvollste zu sein, da 
ich an der Hardware nichts mehr ändern kann und auch nicht an das Ram 
unter dem ROM dran komme.

Was ist "einer der vielen Debug Monitore", ich würde nicht einen 
einzigen finden. Und 15 Minuten sicher nicht weil ja eine Kommunikation 
mit dem PC hergestellt werden muss. Es gibt es sicherlich keine Out of 
the Box Komplettlösungen, also den Server im Z80 und den Cliebt im PC, 
oder? Und dann bitte auch die USB Kommunikation dazu. Den STI wird wohl 
keiner kennen, den muss ich zuerst schreiben, bzw die putchar und 
getchar Routinen.

Sobald das steht geht alles viel fixer.

Nochmal PC:

Kann es wirklich sein, dass ein

cat main.hex >> /dev/ttyUSB0

ausreicht um den Code in den Z80 zu schiessen? Ich meine so einfach?
Zumindest wenn der mit dem Lesen mitkommt, denn beim Handshake wird es 
schwieriger, das habe ich nämlich nicht. Maximal Software HS aber kein 
RTS/CTS.

von Christian J. (Gast)


Lesenswert?

Nochmal zum Debugger

Ich habe da einen "NoIce" Debugger gefunden,der nur leider 30 Tage 
Version ist und sich auch ständig unter XP mit einer Schutzverletzung 
verabschiedet. In dem Paket ist eine IDE mit etwas Komfort, die ein hex 
einlesen kann oder ein Projekt File mit Debug Infos. Auf dem Zielsystem 
wird ein Monitor installiert, der "blind" angepasst werden muss an die 
Serielle. Die IDE kommuniziert mit dem Monitor so als würde man den Code 
Single Steppen. Eben das was auch JTAG kann, oder Linux oder, oder oder.

Das wäre schon sehr nett, wenn es das als Freeware gäbe und es nicht 
ständig abstürzen würde.

Wenn ich mich zurück erinnere an meine Jugend, so war der C64 damals 
Eprommer und der Code für das 8085 musste einfach fehlerfrei geschrieben 
werden. Eine andere Möglichkeit hatte ich nicht mit Hausmitteln.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Kann es wirklich sein, dass ein
> cat main.hex >> /dev/ttyUSB0
> ausreicht um den Code in den Z80 zu schiessen? Ich meine so einfach?

Nein, einfacher, wenn du dich endlich vom Hexfile lösen würdest. Da 
deine Probleme primär auf der Z80-Seite liegen, solltest du zumindest in 
der ersten Stufe deren EPROM-Bootloader so einfachst wie möglich 
halten, und da ist eine umständliche Hexfile-Dekodierung in der Z80 
unnötig.

Was du brauchst ist ein Binärimage des Codes, von beispielsweise exakt 
8kB Länge. Dann die Z80 resetten, damit der Bootloader aktiv wird, und:
  cat main.bin > /dev/ttyUSB0
Nur solltest du die TTY so einstellen, dass darin kein 
Software-Handshake und keine CRLF-Translation stattfinden kann (=> 
stty), denn die muss dafür 8-Bit transparent sein.

> Zumindest wenn der mit dem Lesen mitkommt, denn beim Handshake wird es
> schwieriger, das habe ich nämlich nicht.

Vergiss Handshake. Bei 57600 kriechen 5760 Bytes pro Sekunde über die 
Leitung. Das sind grob 500 Takte pro Byte. Da muss niemand warten.

: Bearbeitet durch User
von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

wenn ich das recht sehe ist dein ROM gesockelt?

Huckepack ein SRAM drauf und RD/WR-Bein hoch und einen Fädeldraht 
rausgezogen. Das ist kein Hexenwerk, so habe ich in fertigen Gräte neben 
den Bios ROM ganze dynmische RAM-Bänke ergänzt sowie IO Ports um 36Bit 
parallel erweitert.
Das war damals Homebrewstandard mehr Retrofealing geht gar nicht.

Namaste

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Christian J. schrieb:
> Was ist "einer der vielen Debug Monitore"

Kannst gern ein Muster von mir bekommen. Allerdings für einen "normalen" 
Assembler (M80 kompatibel, den kannst du mit Doku auch bekommen), 
eventuell will der mit dem SDCC gelieferte nicht.

Du musst nur die Initialisierung deines UART anpassen (Tabelle, Port, 
Wert, der da rein soll) und die getchr und putchr Routinen (da muss man 
vermutlich nur die Position des Statusbit anpassen).

Auf der PC Seite nimmst du Teraterm oder was ähnliches. Und das Laden 
des zu prüfenden Programms geht mit "R", gefolgt von "File senden" in 
Teraterm. Handshake und ähnliches wird nicht gebraucht.

Das Ding ist keine eierlegende Wollmilchsau, reicht für 99.9% aller 
Fälle aber aus.

[code]
Befehlsliste:
        defb    'd<start>,<ende>              = Speicherdump',0dh,0ah
        defb    'f<start>,<ende>,<wert>       = Speicher fuellen', 
0dh,0ah
        defb    'g<start>[,<break1>[,break2]] = Programm ausfuehren', 
0dh, 0ah
        defb    'h<a>,<b>                     = a + b, a - b', 0dh, 0ah
        defb    'i<port>                      = Port lesen', 0dh, 0ah
        defb    'm<von>,<bis>,<nach>          = Speicher verschieben', 
0dh, 0ah
        defb    'o<port>,<wert>               = Port schreiben', 0dh, 
0ah
        defb    'r<offset>                    = Hex-File lesen',0dh,0ah
        defb    's<adresse>,<wert>            = Speicher aendern', 
0dh,0ah
        defb    'w<von>,bis>                  = Hex-File schreiben', 
0dh,0ah
        defb    'x[<register>[,<wert>]]       = Register 
anzeigen/aendern', 0dh, 0ah
[\code]

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?


von Holm T. (Gast)


Lesenswert?

Habt Ihrs noch nicht verstanden?
Christian möchte eine grafische Entwicklungsumgebung unter Windows, also 
mit Debugger, die Ihm Programme auf seine Hardware lädt und dort test- 
und ausführbar macht.
Was er nicht möchte ist:

1. Selber machen
2. Doku lesen
3. sich anstrengen.

Also bitte Jungs, das Ding sollte bitteschön schon fertig sein...
Interfaceroutinen sollten ebenfalls vorhanden und getestet sein so das 
er sie nur noch einbinden muß. Es geh ja nicht das er sich auch noch mit 
Registerpointern herumärgern muß.

SCNR,

Holm

von Soul E. (Gast)


Lesenswert?

gibt's doch alles: http://www.arduino.cc/

von Matthias (Gast)


Lesenswert?

@Winfried was für ein Atari ist das ? 800XL ?

von Holm T. (Gast)


Lesenswert?

Ich möchte im Zusammenhang mit Retro mal auf einen Thread im Robotron 
Forum aufmerksam machen:
http://www.robotrontechnik.de/html/forum/thwb/showtopic.php?threadid=11373

Da möchte Jemand den DDR LC80 als Platine neu auflegen und hat das zur 
Diskussion gestellt. der LC80 ist ein Einplatinenrechner aka 
Mikroprofessor o.Ä. mit 7-Seg Anzeige und Hexa Tastatur.

Um meinem Sohn evtl. was Sinnvolles beibringen zu können würde ich so 
ein Teil evtl. bauen wollen, vielleicht gibts hier noch mehr 
Interessenten die die Platinenkosten drücken helfen oder Vorschläge 
haben.
Ich bin nicht der Threadersteller da, nur interessiert..

Gruß,

Holm

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Axel Schwenke schrieb:
>> Und wozu brauche ich diese verdammten ' Register im Z80?
>
> Wenn du den zweiten Registersatz nicht brauchst, dann benutze ihn halt
> nicht. Andere freuen sich, daß sie ein paar extra-Register haben aber du
> maulst nur rum.

Damit kann man prima Kleinstprogramme bauen, ohne auch nur ein Byte RAM 
extern zu brauchen. Ich hab mal ein Miniboard mit Z80 gemacht, indem 
dann die beiden obersten Adressleitungen Output Ports waren, Input lief 
über einen simplen 74244. Mit Oszillator und EPROM waren das dann 4 
integrierte Schaltkreise.

von Soul E. (Gast)


Lesenswert?

willst du die Melodieklingel nebenher laufen lassen ;-)

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Matthias schrieb:
> @Winfried was für ein Atari ist das ? 800XL ?
130XE mit 800XE Platine aber ein erweiterter 800XL ist auch noch hier ;)

Die 130er Platine mit 1 MB RAM hat meine EX auf dem Gewissen. 
Silberleitlack hineingegossen als Frustkompensation. Sehr effizient 
gewesen die Platine war nicht zu retten.:(

Also nie die OW unterschätzen ;)

: Bearbeitet durch User
von heute unangemeldet (Gast)


Lesenswert?

Holm Tiffe schrieb:
> Ich möchte im Zusammenhang mit Retro mal auf einen Thread

An die Freunde des 8bit-Retrocomputing: Schaut auch mal hier
ins Nachbar-Forum: Beitrag "8bit-Computing mit FPGA"

von Holm T. (Gast)


Lesenswert?

Ja, KC87 auf FPGA.
Das ist allerdings genau das, was ich nicht will. Man kann sich den FPGA 
nämlich dann auch ganz kneifen und das Problem mit JKCEMU abwickeln.

Gruß,

Holm

von Michael_ (Gast)


Lesenswert?

Holm Tiffe schrieb:
> Ich möchte im Zusammenhang mit Retro mal auf einen Thread im Robotron
> Forum aufmerksam machen:
> http://www.robotrontechnik.de/html/forum/thwb/showtopic.php?threadid=11373

Danke für den Hinweis!
Der derzeitige Preis geht doch. Vor einem Jahr hab ich eine leere Z-1013 
Platine in der Bucht angeboten und die haben mir freiwillig 40 EUR dafür 
überlassen.

von heute unangemeldet (Gast)


Lesenswert?

Holm Tiffe schrieb:
> Ja, KC87 auf FPGA.
> Das ist allerdings genau das, was ich nicht will. Man kann sich den FPGA
> nämlich dann auch ganz kneifen und das Problem mit JKCEMU abwickeln.

Falls sich das auf den vorherigen Beitrag von mir bezieht:
Eine FPGA-Realisierung hat mit Software-Emulation rein gar
nichts zu tun. Im FPGA werden alle Gatter und Flipflops
des Zielsystems eins zu eins realisiert.

von Ale (Gast)


Lesenswert?

Wegen 680x0 und Propeller... man kann es auch in einem FPGA 
realisieren... Aber mindestens 30k LE verdenken gebraucht.

Schaltungen sind verfügbar wenn jemand es möchte. Viel Code habe ich 
leider nicht geschrieben, auch verfügbar. Die Platinen waren nicht genau 
was ich wollte. Jetzt versuche ich mit RISCV und FPGAs.

von Schneckenzüchter (Gast)


Lesenswert?

O.T.

>Axel Schwenke schrieb:
>> Schnecken dressieren.

>Davon kann ich nur abraten! Wenn du da nicht die ganze Zeit aufpasst wie
>ein Schießhund, dann brechen die aus. Ein winziger Moment nachlassender
>Aufmerksamkeit und die sind über alle Berge auf und davon, die erwischt
>du nie wieder. ;-)

Als mir neulich eine Weinbergschneck abgehauen war, hatte ich sie 
ruck-zuck eingefangen: Ein Steinpilz war vor ihr aus dem Boden 
geschossen und hatte den Fluchtweg verstellt.

von Konrad S. (maybee)


Lesenswert?

Schneckenzüchter schrieb:
> Als mir neulich eine Weinbergschneck abgehauen war, hatte ich sie
> ruck-zuck eingefangen: Ein Steinpilz war vor ihr aus dem Boden
> geschossen und hatte den Fluchtweg verstellt.

Glück gehabt! ;-)

von Holm T. (Gast)


Lesenswert?

heute unangemeldet schrieb:
> Holm Tiffe schrieb:
>> Ja, KC87 auf FPGA.
>> Das ist allerdings genau das, was ich nicht will. Man kann sich den FPGA
>> nämlich dann auch ganz kneifen und das Problem mit JKCEMU abwickeln.
>
> Falls sich das auf den vorherigen Beitrag von mir bezieht:
> Eine FPGA-Realisierung hat mit Software-Emulation rein gar
> nichts zu tun. Im FPGA werden alle Gatter und Flipflops
> des Zielsystems eins zu eins realisiert.

...das halte ich zwar im konkreten Falle so wie Du es schreibst für ein 
Gerücht, aber ja, ich weiß was ein FPGA ist und was es tut und nein, ich 
schrieb schon, so Etwas will ich gerade nicht.

Eine FPGA Platine sieht genauso aus wie ein Handy von innen und tut 
irgend Etwas, das kann ich einem 9 Jährigen weiß Gott nicht zum lernen 
vorsetzen.
Es ist dann für mich einfacher auch das FPGA zu emluieren, jetzt 
verstanden?

BTW: mir ist klar das man hier als Gast schreiben kann und sich nennen 
kann wie man will, aber muß das so bescheuert sein? Kannst Du Dir nicht 
wenigstens einen Tarn-Vornamen einfallen lassen?

Gruß,

Holm

von bko (Gast)


Lesenswert?

Schätze mal das war Josef mit seinem Sauerbiercomputer
Beitrag "Re: Retro Fieber: Z80 oder 68000 ?"

von Christian J. (Gast)


Lesenswert?

Georg G. schrieb:
> Kannst gern ein Muster von mir bekommen. Allerdings für einen "normalen"
> Assembler (M80 kompatibel, den kannst du mit Doku auch bekommen),
> eventuell will der mit dem SDCC gelieferte nicht.

Hi,

kannst Du mir das hier mal posten? Danke!

Gruss,
Christian

von Christian J. (Gast)


Lesenswert?

Hi,

nur mal so als Info für jene, die vielleicht auch an sowas Spass haben. 
Der SDCC Compiler ist in seiner Version 3.3.0 relativ fehlerfrei, 
erzeugt aber doch umständlicheren Code als man in Asm schreibt. Klar, 
ist eben ein Baukasten. Mit Z80 Interrups kann er nichts anfangen. Die 
crt0.s muss unbedingt angepasst werden, die mitgelieferte erzeugt nicht 
lauffähigen Code und enthält Zeugs, was niemand braucht, löscht man es 
läuft es nämlich alles. Ich habe Stunden gebraucht das heraus zu finden.

Aufpassen muss man allerdings, dass die Debian Repos nur bis zur Version 
3.0.0 reichen von 2012 und da sind noch eine Menge Bugs drin bzw passt 
die Aneitungen einfach nicht zu dem Compiler da zb auch im ASZ80 
Assembler einiges geändert wurde. Am besten zieht man sich den Source 
Code hier runter da immer die aktuellen Snap Shots vorhanden sind

http://sdcc.sourceforge.net/snap.php

und kompiliert sich das Ding selbst, auf meinem Cubie Board, wo ich die 
Z80 Geschichte mache sind das gefühlte 20 Pakete Nachinstallation 
(gputils, libboost-system-tools usw) da ./configure ständig meckert. 
Nach ca 2 Stunden ist das Cubie Board mit dem Kompilieren auch durch.

Von den Libs ist der SDCC soweit brauchbar,l auch ein malloc ist 
vorhanden, allerdings ist die Heap Grosse auf 1kb gefixt und muss in 
einem Script erst angepasst werden, was tief versteckt im /usr/sdcc 
Verzeichnis liegt. Vermeiden sollte man tunlichst printf, vprintf und 
rand Funktionen zu verwenden, auch keine math.h, da allein rand 2kb 
Speicher frisst und niemand weiss warum. printf sind fast 3kb.

von Elektrobrazzzler (Gast)


Lesenswert?

Christian J. schrieb:

> nur mal so als Info für jene, die vielleicht auch an sowas Spass haben.
> Der SDCC Compiler ist in seiner Version 3.3.0 relativ fehlerfrei,
> erzeugt aber doch umständlicheren Code als man in Asm schreibt

Man kann noch etwas an den Dingen schrauben, so winzig ist das Manual 
mit der Beschreibung aller Optionen nun auch wieder nicht, mit der Zeit 
bekommt man so langsam ein Gefühl dafür. Zwar verwende ich den SDCC für 
8051, nicht Z80. Letztens erzeugte ich damit auch Debug-Code für ein 
SiLabs-Board, geht auch einwandfrei. So habe ich auch für ein modernes 
neueres Board einen unlimitierten Compiler fürs Hobby. Die Profi-Tools 
sind ja preislich für mich unerschwinglich, kleines Hobby eben.

Jedenfalls ist er unlimitiert, kann die ganzen für den 8051 möglichen 
64k Codegröße nutzen, womöglich sogar noch Vielfache davon in Banking, 
und hat diesbezüglich keine Fallstricke.

Allerdings benutzt der SDCC einen 80C517 wie einen simplen 8051. Mit den 
schönen Peripherals wie Multiple Datapointer oder MDU kann er nichts 
anfangen, das muß man sich selbst in die Libraries und Funktionen hinein 
stricken, z.B. in memcpy(). Es ist halt kein teueres Profi-Tool, dafür 
kost er aber nix.

Das Registerfile 80C517.h aus dem SDCC war auch eine mittlere Baustelle. 
Dort standen Register drin, die der 80C517 gar nicht hat. Andererseits 
fehlten wiederum andere. Das war auch einen Tag Anpassung, nur das 
H-File alleine. Ein Softie von Sourceforge hat bei sowas bestimmt einen 
mittleren Anfall bekommen und für eine simple Liste zu erstellen keinen 
Bock gehabt. Kann ich irgendwie sogar ein wenig verstehen, das ist wie 
Doku schreiben, Strafarbeit.

> Vermeiden sollte man tunlichst printf

Willst du denn Zahlenumrechnungen wirklich von Hand machen, also z.B. 
Mehrbyte ADD, SUB, MUL, DIV, BIN-BCD, in Assembler? Aber es geht auch. 
In Zeiten, als noch keine C-Compiler und kein Internet verfügbar waren, 
gewöhnte ich mich auch an sowas.

Ein 80535-Board mit nur 2k ROM mußte ich gezwungenermaßen in ASM 
programmieren. Es kam sogar dort noch auf jedes freie Byte am Ende an. 
Das Board konstruierte eine Semestergruppe mit seinem Prof. mal 
gemeinsam, wobei der Prof. aus der 8048-Ära stammte. Daher wohl das 
2k-EPROM, denn es gab zur Bauzeit ca. 1990 auch schon 32k-EPROM, wenn 
nicht sogar 1 MByte.

Ich lese gerade, daß es den SDCC jetzt in 3.3.0 gibt, habe noch 3.2.0.


So, ab heute gehts aber an mein neues PICkit 3 Debug Express. Es liegt 
noch verpackt vor mir. Dabei ist ein einfachstes Board mit weitgehend 
nur einem PIC18F45K20 drauf, einer frei bestückbaren 
Experimentierfläche, und raus geführten Pins, dazu bestellte ich noch 
ein paar PIC18F26K20 DIL28 fürs Steckbrett mit. Das ist fast der gleiche 
wie auf dem Board, nur eben weniger Pins, kein Flat Pack, aber mit 
doppelt großem RAM und Flash.

Mal sehen, ob ich daran Spaß bekomme. Sie stellen mein Intel-Gedönse mit 
80xx performancemäßig auch etwas in den Schatten.

Die ERRATA-Liste beeindruckte mich etwas, aber mal sehen, vielleicht ist 
das halb so wild wie es aus sieht.

von Christian J. (Gast)


Lesenswert?

Elektrobrazzzler schrieb:
> Ich lese gerade, daß es den SDCC jetzt in 3.3.0 gibt, habe noch 3.2.0.

Die neueste Version ist 3.4.1. vom 18.10.2014. Habe die gestern als 
Source durchkompiliert. 80535 war bei mir Studium, hatte etliche davon. 
Alles schon damals mit Keil in C.

von Christian J. (Gast)


Lesenswert?

Mit dem PIC18F45K20  habe ich ein Industriedesign gemacht, 2 Stück, 2 
Kanalig. Mit CCS als Compiler. Er funktioniert wie jeder andere 
Controller auch, da es bei C sowieso egal ist welchen man nimmt. Ich 
arbeite mit PIC seit gut 18 Jahren, seit der erste herauskam. Damals nch 
mit dem völlig fehlerhaften Bytecraft Compiler, seit 1997 mit CCS. Nur 
musste ich es vermeiden Libs zu nehmen, die die Peripherie einbetten, da 
der TÜV den Code zeritifzieren musste. Den CCS kann man sich "besorgen" 
wenn man weiss wo man suchen muss. Es ist ein hochwertiger Compiler, hat 
aber leider keinen Linker. Es darf nur ein File geben, man muss alles 
andere mit Include einbinden und darauf achten, dass man für jede 
Funktion Prototypen in main.h definiert.

Der schönste Controller, den ich bisher hatte mit den meisten Features 
und Ressourcen war der ARM7, LPC2368 mit GCC Compiler. Allein 40kb Ram 
onchip, 512kb Flash, Batterieram auch noch, USB Ram 16kb usw. Man kann 
das Programm im RAM entwickeln wenn es nicht größer als 32kb wird und 
erst dann flashen, da er Code aus dem Ram aus führen kann. Bootloader, 
Startup Code usw., macht alles die Rowley IDE, da muss man sich nicht 
drum kümmern. Heute erzeugt die auch den Code für den Clock, man stellt 
nur ein was man haben will und die bindet das mit ein.

Allerdings eben 32 Bit und nicht mehr so einfach zu verstehen. SD 
anbinden bin ich gescheitert und musste fertigen Code nehmen, da ich die 
Einarbeitung in das SD Protokoll vermeiden wollte, sondern nur 
Funktionen nutzen. Allein die Clock und PLL einzustellen, sowie den APB 
Bustakt sind viele Zeilen Code. Aber mit 80Mhz rennt der auch.

von Georg G. (df2au)


Angehängte Dateien:

Lesenswert?

Christian J. schrieb:
> annst Du mir das hier mal posten?

Dann mal eine Jugendsünde. Das Ding läuft in einem Flash und kann sich 
selbst aktualisieren. Es gibt auch noch Versionen mit Unterstützung für 
1791 Floppy Controller oder WD1002 Harddisk Board.

Als Assembler-Linker-Locater-Librarian verwende ich eine M80-L80-Lib80 
kompatible Version von M. Röhner. Wenn es C sein soll, ist es eine 
Variante von QC. Diese Werkzeuge sind nur für nicht kommerzielle 
Anwendungen frei.

von Christian J. (Gast)


Lesenswert?

Danke, sieht doch schön aus und ist gut dokumentiert. Werde sicher 
einiges da rauskopieren. Wie man bei Assembler von "struktrierter 
Programmierung" sprechen kann wird mir allerdings ewig ein Rätsel 
bleiben, für mich bleibt das ein Aneinander klatschen von Routinen ohne 
gescheite Parameter Übergabe und Techniken wie Variablen Overlaying sind 
da ganz abhanden gekommen.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Eine Sünde finde ich nicht auf anhieb,
wirkt recht aufgerämt auf mich.

Namaste

von Georg G. (df2au)


Lesenswert?

Christian J. schrieb:
> ewig ein Rätsel bleiben

Du bist eindeutig etwa 30 Jahre zu spät geboren. :-)

(Wobei früher nicht alles schlechter war. Nur so ein Beispiel: 
Wordmaster konnte man 10-Finger-blind schreiben. Und Rechtschreib 
Korrektur und Drucken im Hintergrund konnte der auch schon.)

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Georg G. schrieb:

> Du bist eindeutig etwa 30 Jahre zu spät geboren. :-)

Mag sein, gewissen Dingen kann ich ja noch einen gewissen Charme 
abgewinnen, wie in dem Beispiel das Laden von Ports mit 
Konfigurationdaten. Zumindest wenn man schn mitzählt wo der Pointer 
hochgezählt wird bzw runtergezählt. Trotzdem keine Ahnung wie man einen 
Befehl OUTI ausdenken kann, oder OTIR der wahrscheinlich genau dafür 
gemacht wurde. Typisch CISC Maschine.

Nen freien, grafisch zu bedienenden (ja, ich will das!) Simulator habe 
ich immmer noch nicht gefunden, werde wohl die 25 Euro für einen 
ausgeben, der recht nett gemacht ist.

Spasseshalber habe ich mir mal den Quellcode eines 4 Gewinnt Spieles 
gegen den Computer besorgt. Das kann man dann auch so umprogrammieren, 
dass er ständig gegen sich selbst spielt. Kompiliert bisher einwandfrei 
durch, auch wenn rand etc viel Speicher braucht. Bin mal gespannt wie 
das Gewinnverhältnis nach ein  paar Stunden sein wird, ob Computergegner 
1 oder 2 mehr Spiele gewinnt. Heute abend mal an die STI rangehen und 
die verdrahten, damit endlich auf dem PC was zu sehen ist.

Erinnert mich so ein wenig an "Wargames" :-)

Na hauptsache der Z80 ist beschäftigt und sei es nur mit sich selbst :-)

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Nochmal ein Special für A.K.:

Ich programmiere grad Code für den MK3801 und bin da noch etws unsicher.
Weiter oben siehst du einen Auszug aus einer Appnote, die ich übersetzt 
habe.

Müssen die Uart Eingänge RC (Receiver Clock Input) und TC (Transmitter 
Clock Input) alle beide an den Ausgang des Timers D angebunden werden, 
der dann die Baudrate erzeugt?  Async übertragung wird durch Sampling 
bewerkstelligt, d.h. wird hier mit 1:16 abgetastet?

Ich verstehe auch nicht ganz wieso die die PIO Ports im DDR Register auf 
0x64 geetzt haben? Die haben doch mit der UART nix zu tun, oder? Was hat 
dieser Codefetzen da verloren?

PS:L Der MK3801 schraubt sich unglaubliche 180ma rein! Mit der NMOS CPU 
frisst die Karre jetzt schon 380mA auf 100km !!!

1
  // STI konfigurieren für Uart Ausgabe
2
  STI_UCR = 0x88;        // = 10001000  UART Control Register 8N1, DIV16
3
  STI_RSR = 0x01;        // RX Status - Enable RX
4
  STI_RSR = 0x01;        // TX Status - TX High, TX enabled
5
  STI_PVR = STI_DDR;      // Zeiger PVR auf indirect 6 (DDR)
6
  STI_IDR = 0x64;        // ???? Was soll das?
7
  STI_PVR = STI_TDDR;      // Zeiger PVR auf Timer D Data
8
  STI_IDR = 0x03;        // Timer D Zeitkonstante
9
  STI_PVR = STI_TCDCR;    // Zeiger auf Timer C,D Control Register
10
  STI_IDR = 0x89;        // Timer D DIV 4, C = Stop

Defintionen:
1
  0x00    IDR   Indirect Data Register
2
  0x01        GPIP   Purpose I/O Data Register
3
  0x02    IPRB   lnterrupt Pending Register B
4
   0x03    IPRA   Interrupt Pending Register A .
5
  0x04    ISRB   Interrupt -Service Register B
6
  0x05     ISRA   Interrupt in-Service Register A
7
  0x06    IMRB   lnterrupt Mask Register B
8
  0x07    IMRA   Interrupt Mask Register A
9
  0x08    PVR   Pointer,/Vector Register
10
  0x09    TABCR   Timers A and B Control Register
11
  0x0A     TBDR   Timer B Data Register
12
  0x0B     TADR   Timer A Data Register
13
  0x0C     UCR   USART Control Register
14
  0x0D     RSR   Receiver Status Register
15
  0x0E     TSR    Transmitter Status Register
16
  0x0F     UDR   USART Data Register  
17
18
// Indirekt adressbierbare Register des STI
19
20
#define   STI_SCR    0    // Sync Character Register
21
#define   STI_TDDR  1    // Timer D Data Register
22
#define    STI_TCDR  2    // Timer C Data Register
23
#define    STI_AER    3    // Active Edge Register
24
#define    STI_IERB  4    // Interrupt Enable Register B
25
#define    STI_IERA  5    // Interrupt Enable Register A
26
#define    STI_DDR    6    // Data Direction Register
27
#define    STI_TCDCR  7    // Timer C und D Control Register

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Müssen die Uart Eingänge RC (Receiver Clock Input) und TC (Transmitter
> Clock Input) alle beide an den Ausgang des Timers D angebunden werden,
> der dann die Baudrate erzeugt?

Kannst auch einen anderen Timer verwenden, aber ohne RC/TC UART Takt 
wird es nichts mit der UART.

> Async übertragung wird durch Sampling
> bewerkstelligt, d.h. wird hier mit 1:16 abgetastet?

Korrekt. Das ist bei fast allen UARTs so.

> PS:L Der MK3801 schraubt sich unglaubliche 180ma rein! Mit der NMOS CPU
> frisst die Karre jetzt schon 380mA auf 100km !!!

Tja nun, NMOS frisst Dauerstrom. Da spürt man, wo der Strom landet.

>   STI_PVR = STI_DDR;      // Zeiger PVR auf indirect 6 (DDR)
>   STI_IDR = 0x64;        // ???? Was soll das?

Bei mit steht da 0xA7, wegen /BOOT,5",FDC-TC,/STROBE,RTC-DATA.
Soll heissen: Das hängt davon ab, was an den Pins dran hängt. Da der 
gezeigte Code wohl nicht von dir ist, hängt das von dem System ab, wovon 
du den Code kopiert hast.

Der Anhang sieht eher nach deiner Platine als nach einer Appnote aus. 
Und deine UART Taktverdrahtung solltest du mal überprüfen, denn so wie 
gezeigt wird das nix.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Der Anhang sieht eher nach deiner Platine als nach einer Appnote aus.
> Und deine UART Taktverdrahtung solltest du mal überprüfen, denn so wie
> gezeigt wird das nix.

Yep ... Pindreher. Im Schaltplan falsch, am Board aber richtig.

Die Appnote sollte eigentlich nur die UART behandeln, da denkt man sich 
ja nicht, dass die die PIO noch für was anderes brauchen. Hätte ja sein 
können, da manche Pins noch extra auf Output geschaltet werden müssen. 
Ist ja oft dass keinen Override gibt, wenn Pins mehrere Funktionen 
haben.

von (prx) A. K. (prx)


Lesenswert?

Wozu dient eigentlich R26? Falls der für NMI ist: Der INT Ausgang vom 
STI ist Open Drain, der INT Pin braucht also auch einen.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Wozu dient eigentlich R26? Falls der für NMI ist: Der INT Ausgang vom
> STI ist Open Drain, der INT Pin braucht also auch einen.

In dem Board ist da auch einer (smd), nur im Schaltplan leider vergessen 
:-( Habe alle Ints an 10K gehängt.

Ab 3 Drähte an einem Lötpin wird es eng.... Datenbus ist ja überall 
dran.

Den MK3801 gibt es nicht zufällig als CMOS..... 37 Grad hat der laut 
Messung.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> 37 Grad hat der laut Messung.

Na und? Bei 900mW hätte ich etwas mehr erwartet. Gemessen oder aus dem 
Datasheet abgeschrieben?

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Mit der Infrarot Pistole gemessen. Inzwischen sind es 43 Grad.

Es gab noch einen 68...irgendwas 901 von Thompson als CMOS, der ein 
aufgebohrter STI ist mit 48 Pins aber dann eben kein 2,54er Raster mehr.
Der Stromverbrauch nervt doch etwas. Die ersten 7400 die ich noch hier 
habe fressen auch 50mA pro Stück.

Die Suche bringt auch nicht mehr hervor, außer diesen Thread der 
inzwischen indiziert wurde.

So, mir tun die Augen weh trotz Lupenlampe unter der ich das verdrahte. 
Zeit aufzuhören....

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Mit der Infrarot Pistole gemessen.

Ich dachte eher an den Strom.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Christian J. schrieb:
>> Mit der Infrarot Pistole gemessen.
>
> Ich dachte eher an den Strom.

Also, A.K. .... so schwer ist es ja nicht an der Anzeige eines PS den 
Strom abzulesen vor und nachdem man den Chip reingesteckt hat. Und der 
ist 180ma höher als vorher.

von Bart (Gast)


Angehängte Dateien:

Lesenswert?

so als inspiration :-)
Nen OS für den Z80 mit Multitasking, Windows, Task Manager etc :-)

von Bart (Gast)


Lesenswert?


von Bart (Gast)


Lesenswert?


von Bart (Gast)


Lesenswert?

sorry ich das hier mit meiner Begeisterung zumülle, aber das ist einfach 
zu geil!
Mit Videoplayer und einem VDP9990 graphic chip für z80
https://www.youtube.com/watch?v=a6v2EFAhiQA

von Christian J. (Gast)


Lesenswert?

@A.K.

Der MK3801 spielt einwandfrei. Und nochwas ..pssst.... : Die Timer 
laufen rückwärts..igitt! Und bei 0 heben die den Pin hoch und einen Takt 
später wieder runter, laden sich wieder mit ihrem Reload Wert. PWM geht 
auch.

Aber nicht weitersagen! :-)

von (prx) A. K. (prx)


Lesenswert?

Wieso igitt? So kann man den Teiler direkt eintragen, wie schon aus den 
gezeigten Initialisierungswerten hervorging.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Wieso igitt? So kann man den Teiler direkt eintragen, wie schon aus den
> gezeigten Initialisierungswerten hervorging.

Das war ein kleiner ironischer Witz......

Muss nur noch rausfinden, was der sdcc anstellt, wenn man 
read/modify/write Operationen auf den Ports auführt. Ob da der richtige 
Code bei rauskommt.

Nein, erzeugt einen "fatal internal compiler error"

if (stat==TRUE)  // Bit ein
       STI_GPIP |= (1<<bitnr);

I/O können nur geladen, verändert und zurück geschrieben werden.

von Christian J. (Gast)


Lesenswert?

Kurz, da ich derzeit immer noch "blind" programmiere, bis die Leitung 
zum PC endlich steht:

Interrupt im MK3081 aber auch generell: Es gibt für die UART

Interrupt ENABLE Register
Interrupt MASK Register
Interrupt PENDING Register

Ist das richtig:

enable = 0, mask = 0;

=> es wird weder ein Hardwarevorgang ausgelöst, noch wird das pending 
bit gesetzt, wenn ein Zeichen kommt.

enable = 1, mask = 0;

=> es wird pending gesetzt und kann gepollt werden, aber es wird kein 
Hardware Int ausgelöst, weil der Int "ausmaskiert" ist. pending muss 
manuell gelöscht werden, ggf. durch auslesen des registers?

enable = 1, mask = 1;

=> pending wird gesetzt, hardware int wird ausgelöst, vektor geht auf 
den bus, pending wird automatisch gelöscht, sobald die Z80 den Vektor 
entgegen nahm und IOREQ und M1 gezogen hat.

von Christian J. (Gast)


Lesenswert?

Und bevor es ins Bett geht (und der Thread versickert) noch eine Sache:

Interrupts und Timer A testen. Hardware und Software.
Zunächst Mode 1, da einfacher.

Test 1: INT Pin und Software

1. 0x38 zeigt auf Routine, die LEDs durchzählt
2. im 1
   ei
im Hauptprogramm

3. Stück Draht an Pin 16 (INT) und Masse anticken
=> LEDs zählen hoch. INT ist pegelgetriggert wie ich sehe

Test 2: Timer A testen

1. Timer A konfigurieren
2. Hauptprogramm schleife zeigt Timer A Data auf LEDs an (mit delay)
=> Timer A laeuft und reloaded richtig, Bits schnubbeln auf die LEDs

Test 3: Timer A Interrupts bei Nulldurchgang sollen Int Mode 1 (0x38) 
triggern
1. Timer A enable Bit = 1
2. Timer A Mask Bit = 1
3. Timer A Reload Wert 0xff und DIV 200, damit man was sieht

Läuft nicht! Pin INT wird nicht von Timer A Int über INT Pin getoggelt. 
Test mit Drahtstück klappt aber.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Interrupt ENABLE Register
> Interrupt MASK Register
> Interrupt PENDING Register

Und optional das "Interrupt in-Service Register". Relevant wenn man 
verschachtelte Interrupts zulassen will.

> Ist das richtig:

Ja.

> manuell gelöscht werden, ggf. durch auslesen des registers?

Steht doch in der Doku. 0 schreiben löscht, 1 unverändert.

von Christian J. (Gast)


Lesenswert?

Ich kriege leider trotzem keine kontinuierliche INT Auslösung. Nur mit 
dem Draht, also kommt vom MK3801 nichts.

Was fehlt denn jetzt noch, damit der Timer Überlauf eben dauerhaft Ints 
auslöst? Zumindest Mode 1 schonmal, Mode 2 wird dann sicher auch 
funktionieren.

PS: Erledigt. Man sollte nicht eine Hardware in Main und im Int 
ansprechen, das gibt Murks.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Und auch das Thema ist damit erledigt ..... puhhh.

Blöd ist der Compiler ja nicht:

aus

while ((STI_TSR & 0x80) == 0);   // Warte bis Buffer frei...

wird:

00101$:
  in  a,(_STI_TSR)
   rlca
   jr  NC,00101$

von Georg G. (df2au)


Lesenswert?

Christian J. schrieb:
> Blöd ist der Compiler ja nicht:

Nimm dir mal einen alten 4MHz Z80 CP/M Kasten (fairerweise mit Harddisk) 
und einen modernen PC. Und dann nimm dir Wordstar und Word und lass eine 
Sekretärin, die richtig Schreibmaschine kann nacheinander auf beide 
Kisten los. Das Ergebnis wird dich verblüffen.

Damals (tm) wurde noch mit Hirn und Nachdenken programmiert. Es gab kein 
Klicki Bunti Mausgeschiebe. Aber die Ergebnisse konnten sich sehen 
lassen.

von Christian J. (Gast)


Lesenswert?

Hallo,

der Thread ist inzwischen abgesoffen und hat sich auf einen 
Nebenschauplatz verlegt, wo internste Details des sdcc Compiler geklärt 
werden mussten, weil der damit nicht so recht klarkommt globale 
Variablen zu intitialisieren. Dazu musste dieses Loch erst bis zur Sohle 
beschritten werden und ein Programmierer des sdcc leistete dazu 
wertvolle Hilfe,den ich angeschrieben hatte.

Beitrag "Re: Mehrdimensionale char-arrays"

Es funktioniert bisher alles, auch die Mode 2 Ints aber dieser 
Mechanismus ist ja fix installiert, was soll da also schief gehen. Am 
Monitor bin ich dran, weiss noch nicth genau wieviel ich im Int 
erledigen soll, schöne Konstrukte mit FIFO Buffer usw oder ob alles in 
einer Polling Schleife? Vielleicht noch Basic Interpreter dabei, Hex 
Dump usw. Wird sich zeigen. Der Z80 sendet und empfängt Zeichen.

Damit wäre dieser Thread also am Ende und wenn jemand auf die gleiche 
Idee kommt und den sdcc verwendet, so sind da alle Probleme bisher 
gelöst worden. Die Hardware ist abgetrennt vom User Code, ein HAL liegt 
bei mir jetzt dazwischen. Zumindest bis auf den Umstand, dass man keine 
static Variablen in Ints verwenden kann, die nicht 0 sind. Das kann er 
(noch) nicht.

Jo, danke an alle hier und die Geduld.....Einarbeitung war erfolgreich. 
Und Asm echt nur da wo unbedingt nötig. Ich mag kein Asm und auf Zeit 
kommt es eh nicht an.

Gruss
Christian

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

retrogerecht
1.FIFO gab es zu Z80 nicht manlegte ringbuffer mit overflowflag an.
2.Static erledigt man in einem eigen Variablenbereich welcher der 
Funktion zugeordnet ist. Also nicht im variablenbereich von main liegt 
und welcher so für den rest des Programms invisible bleibt. wärend 
Global entweder von main angelegte werden oder durch die installierende 
Funktion an den Compiler angemeldet werden damit er sie visible 
generiert.
lokal erledigt mann gern auf dem Stack, mus ihn aber schön aufräumen.

Also nach dem poppen alles sauber aufwischen. ;)

Namaste

von Harald N. (haraldn)


Lesenswert?

Sehr cool! Vielleicht kannst du ja für die Nachwelt dein Endergebnis in 
Hardware und Software hier posten..

von Christian J. (Gast)


Lesenswert?

Hallo,

stellt sich dennoch die ein oder andere Frage, da ich mich mit 
Protokollen von Schnittstellen nicht so genau aus kenne.

Wenn vom PC ein Binärdatenstrom über das USB Interface in die Uart 
reinkommt, wie zeigt dann der PC das Datenende an? Ich habe nur zwei 
Leitungen, RX und TX, kein Hardware Flow Control, kein Handshake. Daten 
die kommen müssen entgegen genommen werden da sie unentwegt 
weiterlaufen.

Kann ich das Datenende nur über Timeout erkennen? Denn die Vereinbarung 
eines speziellen Zeichens geht ja im Binärcode nicht.

Aktuell laufen die Zeichen über den SIO Interrupt rein und füllen einen 
Ringpuffer, der 3/4 "voll" meldet hofft hofft dass das Hauptprogramm 
sich um ihn kümmert bevor Daten verworfen werden.

von Georg G. (df2au)


Lesenswert?

Wenn du kein spezielles Übertragungsprotokoll gewählt hast, hilft nur 
Timeout, mit allen Risiken und Nebenwirkungen. Eben deshalb wurde so 
Dinge wie Z-Modem oder Kermit entwickelt. Flowcontrol hilft dir da auch 
nicht weiter.

von Christian J. (Gast)


Lesenswert?

Hallo,

grundsätzlich kann der Empfänger antworten aber ich will PC seitig 
keinen Aufwand treiben und die Binärdaten nur mit cat daten.bin > 
/ttyUSB0 absenden nachdem die Schnittstelle vorher eingestellt wurde. 
Dazu muss ein Shell Script reichen. Ein Protokoll als Frame fällt daher 
auch flach und ist nicht nötig, ZModem ist ja für Überseeübertragungen 
konzipiert und mir noch aus FidoNet Zeiten bekannt damals.

9600 sind auch "zum mitschreiben". Ok, also Timeout Verfahren, zwei 
rotiernde Zeiger in einem Array, einer der schreibt, der andere der die 
Leseposition nachzieht und aufpassen dass der Z80 keine Zeichen verliert 
da es keine Pausen gibt... schauen wir mal...

von (prx) A. K. (prx)


Lesenswert?

Du denkst viel zu kompliziert. Feste Länge definieren, oder vorneweg 
senden. Das Board erwartet 4K, der Sender sendet 4KB (als Beispiel). 
Auch dein FIFO ist erst einmal unnötig.

Einfacher gehts nicht. Auf die Art kannst du dann beispielsweise einen 
Hex-oder X/Y/Z-Modem/Kermit Loader entwickeln und wenn er läuft diesen 
einbrennen. Oder was auch immer.

Weshalb sollte da was verloren gehen? Hast du hungrige Bitmäuse im Lab?

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Wenn vom PC ein Binärdatenstrom über das USB Interface in die Uart
> reinkommt, wie zeigt dann der PC das Datenende an?

A. K. schrieb:
> Was du brauchst ist ein Binärimage des Codes, von beispielsweise exakt
> 8kB Länge. Dann die Z80 resetten, damit der Bootloader aktiv wird, und:

beispielsweise exakt 8kB Länge
beispielsweise exakt 8kB Länge
beispielsweise exakt 8kB Länge
beispielsweise exakt 8kB Länge

Es können aber beispielsweise auch exakt 4KB Länge sein.


Edit
zu spät

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Hi,

der Compiler spuckt leider nur variable Länge aus und der Binärconverter 
auch. Muss mal schauen ob sich das ändern lässt. Timeout ist mir 
sympathischer, schon damit er sich nicht aufhängt.

Stelle grad fest,  dass der PC 7-bit Daten sendet. Habe mal einiges an 
den Z80 geschickt mit

cat testdatei.bin > /dev/ttyUSB0

und stelle es auf der LED Zeile dar, LED Nr 7 bleibt dunkel, die anderen 
flackern im Bytetakt. 9600... es dauert eben :-)

Muss mal schauen wie ich stty irgendwie umstelle, dass es Binärdaten 
sendet, nicht ganz eays, die Hilfe ist schon erschlagend.

von Christian J. (Gast)


Lesenswert?

Und jetzt habe ich mir auc noch /dev/ttyUSB0 "gelockt" mit screen und 
außer einem Reboot des PC weiss ich auch nicht wie ich das unlocken 
kann.

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> der Compiler spuckt leider nur variable Länge aus und der Binärconverter
> auch.

man objcopy
man dd

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> der Compiler spuckt leider nur variable Länge aus und der Binärconverter
> auch. Muss mal schauen ob sich das ändern lässt.

Und dein PC hat irgendwie jede Fähigkeit verloren, ein Binärfile auf 
feste Länge zu erweitern?

Sowas ist doch schneller programmiert als hier ins Forum getippt. Aber 
geht auch ohne:
  dd if=main.bin of=main.4kb ibs=4k conv=sync

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Und jetzt habe ich mir auc noch /dev/ttyUSB0 "gelockt" mit screen und
> außer einem Reboot des PC weiss ich auch nicht wie ich das unlocken
> kann.

Hast du Angst, dass er beim Reboot nicht mehr hochkommt? Wobei man ein 
TTY mitunter mit "stty sane < /dev/ttyXXX" wieder sauber kriegt. Wäre 
aber sinnvoll, im stty mit deinem USB zu reden, nicht mit der X-Konsole, 
in der du das eintippst.

von Christian J. (Gast)


Lesenswert?

Der Compiler erzeugt keine object files :-(  dd ist sehr praktisch da 
mit bs = 8192 ja die Blockgröße gesetzt werden kann.

Aber egal, 8 Bit sind auch, weil... nun Ascii Textdateien sind nunmal 7 
Bit codiert. So ein 200kb Bild braucht seine Zeit aber der Z80 kommt gut 
mit, bisher keine Zeichen verloren.

Etwas anders wird schon schwieriger.... denn ein Programm im RAM ab 
0x2000, dem fehlen die ganze Zeropage und da liegen bekanntlich einige 
Vektoren. Und ich kann ROM nicht nach RAM überblenden, da das darunter 
liegt. D.h. dass zb Int Mode 2 gar nicht möglich ist, denn der würde auf 
das ROM zugreifen und die Vektoren zeigen irgendwo hin aber nicht auf 
die Routinen im RAm da die jedesmal woanders liegen. Daran habe ich 
leider nicht gedacht, dass alles aus der Zeropage jetzt unerreichbar 
ist. Auch die Software Interrupts RST n, NMI sowieso, alle Timer 
Interrupts usw. Der Compiler lässt es leider nicht zu, dass man Routinen 
fixe Adressen verpasst, der will da sehr frei wählen wo jedes Segment 
liegt.

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

RAMDISK
Bankswitching
Mapping
konnte der Z80 nicht auch Blöcke im RAM per ASM Befehl verschieben?
....
;)

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Der Compiler erzeugt keine object files :-(

Natürlich erzeugt der Compiler object files. Auch wenn sie .rel statt .o 
heißen mögen. Aber das spielt ja hier überhaupt keine Rolle. Falls Du 
den Linker Hex-Files erzeugen läßt (statt bin), könntest Du die mit 
objcopy in Binärfiles konvertieren.

> dd ist sehr praktisch da
> mit bs = 8192 ja die Blockgröße gesetzt werden kann.

Die Blockgröße spielt hier überhaupt keine Rolle.

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:
> Die Blockgröße spielt hier überhaupt keine Rolle.

ibs !!!!!!

Ok, Problem gelöst, braucht nicht mehr diskutiert zu werden.  Alles 
schon fix und foxi in einem Script verarbeitet. Compilieren, Hexen, 
Binären, umwandeln nach 8192 Bytes usw :-)


Das Thema mit den fehlenden Int Möglichkeiten eines Upload Programms 
wird wohl nicht zu lösen sein.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Etwas anders wird schon schwieriger.... denn ein Programm im RAM ab
> 0x2000, dem fehlen die ganze Zeropage und da liegen bekanntlich einige
> Vektoren.

Im IM2 liegen die dort, wo du sie per I Register hinlegst. Dieses 
Register brennt nicht ab, wenn man es im RAM-Code passend verändert.

von Christian J. (Gast)


Lesenswert?

Winfried J. schrieb:
> RAMDISK
> Bankswitching
> Mapping
> konnte der Z80 nicht auch Blöcke im RAM per ASM Befehl verschieben?
> ....
> ;)

Ja, sogar mit ldir in einem Rutsch, so Power Befehle hat der. Nutze ich 
zum Initialisieren der Variablenfelder im Startupcode.

; Initialisiere globale Variablen
  ld  bc, #l__INITIALIZER
  ld  a, b
  or  a, c
  jr  Z, weiter
  ld  de, #s__INITIALIZED
  ld  hl, #s__INITIALIZER
  ldir

Geswitched werden kann da nix, das ist fest verdrahtet und inzwischen 
"unlösbar" in Fädelkämmen. Das RAM liegt unter dem ROM drunter und ist 
unerreichbar. Da sich bei jedem Kompiliervorgang die Adressen ändern 
können die Vektoren nicht mehr benutzt werden. Hätte ich das vorher 
gewusst hätte ich ein Bankswitching eingebaut.

Mir fällt nichts ein um das zu umgehen, Programme werden also int-los 
sein müssen was sehr schade ist, da aktuell der Timer die Hardware 
bedient und im User Code keine direkten HW Zugriffe mehr nötig sind.


>>Dieses Register brennt nicht ab, wenn man es im RAM-Code passend verändert.

Auch das nützt nichts! Denn die Adressen sind vielfache von 0x100 im I 
Register. Denke dass ich einen Compiler nutze wo der Linker diese Arbeit 
abnimmt diese Tabelle an ihre Zielorte zu leiten und dass er das kann, 
weil ihm die Zieladressen bekannt sind, da er crt0.rel und mail.rel zu 
einem verklumpatscht.
1
  ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul
2
  ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle
3
  .org 0x40
4
  .dw (_int_sti_gpi_0)
5
  .dw (_int_sti_gpi_1)
6
  .dw (_int_sti_gpi_2)
7
  .dw (_int_sti_gpi_3)
8
  .dw (_int_sti_timer_d)
9
  .dw (_int_sti_timer_c)
10
  .dw (_int_sti_gpi_4)
11
  .dw (_int_sti_gpi_5)
12
  .dw  (_int_sti_timer_b)
13
  .dw  (_int_sti_transmit_error)
14
  .dw  (_int_sti_transmit_buffer_empty)
15
  .dw  (_int_sti_receive_error)
16
  .dw  (_int_sti_receive_buffer_full)
17
  .dw  (_int_sti_timer_a)
18
  .dw  (_int_sti_gpi_6)
19
  .dw  (_int_sti_gpi_7)

von Leo C. (rapid)


Lesenswert?

A. K. schrieb:
> Im IM2 liegen die dort, wo du sie per I Register hinlegst. Dieses
> Register brennt nicht ab, wenn man es im RAM-Code passend verändert.

Das ist ja gerade die aus allem in der 8-Bit Welt vorher dawesenem 
herrausstechende Eigenschaft des Interrupt Mode 2.

Christian J. schrieb:
> D.h. dass zb Int Mode 2 gar nicht möglich ist, denn der würde auf
> das ROM zugreifen und die Vektoren zeigen irgendwo hin aber nicht auf
> die Routinen im RAm da die jedesmal woanders liegen.

Wo die Vektoren hinzeigen bestimmt einzig und allein der Programmierer, 
und nicht etwa der Compiler oder sonst was.

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:

> Wo die Vektoren hinzeigen bestimmt einzig und allein der Programmierer,
> und nicht etwa der Compiler oder sonst was.

Die CPU erwartet sie da, wo das I-Register hinzeigt! Die einzige 
Möglichkeit die bestünde wäre, das I Register so weit umzubiegen, dass 
es zb auf 0x2000 zeigt, dort liegt eine künstlich erzeugte Tabelle und 
der eigentliche Code beginnt erst bei 0x2100. Trotzdem habe ich (noch) 
keine Ahnung wie ich aus einem laufenden Programm heraus diese Tabelle 
erzeugen kann, da ich dazu die Position von Routinen ermitteln muss.

Ob ein

const int (*myvektor) ptr_int_1;
myvektor = int_routine_1

funktioniert weiss ich noch nicht. C kann bekanntlich Zeiger auf 
Funktionen verarbeiten, die zur Kompilationszeit bekannt sind. Habe ich 
noch nie benutzen müssen sowas.

Da ich die ganze Sache aber noch nicht zu Ende gedacht habe mache ich 
hier keine Schnellschüsse.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Trotzdem habe ich (noch)
> keine Ahnung wie ich aus einem laufenden Programm heraus diese Tabelle
> erzeugen kann, da ich dazu die Position von Routinen ermitteln muss.

Dass du einen Zweifrontenkrieg gegen Hardware und Compiler kämpfst, 
das hast du dir selbst zuzuschreiben. Aber was fürs ROM mit 0x0040 
funktioniert, das funktioniert fürs RAM an 0x2040 genauso.

Du kannst den RAM Code exakt so bauen wie den ROM Code. Nur eben ab 
0x2000 statt 0x0000. Einzig NMIs und die RST-Befehle fallen flach.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Dass du einen Zweifrontenkrieg gegen Hardware und Compiler kämpfst,
> das hast du dir selbst zuzuschreiben.

Da der ganze Apparillo nichts weiter ist als anderen in Kreuzworträsel 
und keinen praktischen Nutzen hat außer Denksport und Spass am 
Problemlösen und Gestalten denke ich, dass man das vernachlässigen kann.

Du wirst sicher zugeben müssen, dass da Auge der Ästhetik unten 
stehendes Codebeispiel ohne Augenkrebs zu bekommen anschauen kann. Auf 
jedenFall sicher besser als eine Tabelle voller Nummern, die per djnz 
Schleife in die Ports geschrieben werden. Und wenn ich Lust habe kriegt 
jedes Bit auch noch eine define Zeile....

Welcher Depp ist eigenlich dafür verantwortlich, dass unter Unix und 
Windows cr/lf und lf als Zeilenende unterschiedlich sind?
1
void InitHardware()
2
{
3
  // 8255: Mode 0: Port A,B,C Output
4
  PIO8255_CNTRL  = 0x80;     //Mode 0: Port A,B,C Output
5
  PIO8255_PORT_A = 0xff;
6
  PIO8255_PORT_B = 0;
7
  PIO8255_PORT_C = 0;
8
9
  // 7-Segment ....
10
  SEG7 = 0xff;
11
12
  // STI konfigurieren für Uart Ausgabe
13
  STI_UCR   = 0x88;      // = 10001000  UART Control Register 8N1, DIV16
14
  STI_RSR   = 0x01;      // RX Status - Enable RX
15
  STI_TSR   = 0x05;      // TX Status - TX High, TX enabled
16
  // Timer D...
17
  STI_PVR   = STI_TDDR;    // Zeiger PVR auf Timer D Data
18
  STI_IDR   = 0x03;      // Timer D Zeitkonstante
19
  STI_PVR   = STI_TCDCR;    // Zeiger auf Timer C,D Control Register
20
  STI_IDR   = 0x89;      // Timer D DIV 4, C = Stop
21
  // GPIO.....
22
  STI_PVR   = STI_DDR;    // Zeiger PVR auf indirect 6 (DDR)
23
  STI_IDR   = 0xff;      // GPIO als Output
24
  STI_GPIP  = 0x00;      // GPIO auf Null setzen
25
  // Timer A = endlos Run 
26
  STI_TADR  = 0xff;      // Reload Wert Timer A
27
  STI_TABCR = 0x70;      // Timer A DIV 200, 255x200 = maximale Verzögerung
28
  STI_PVR   = STI_IERA;    // Timer A /RX Buffer Interrupt einschalten  
29
  STI_IDR   = 0x30;
30
  STI_IMRA  = 0x30;      // Timer A Interrupt / RX Buffer full unmask
31
  STI_IPRA  = 0x00;      //Pending Ints löschen
32
  
33
  // Zuletzt Interrupt Vektor für Mode 2 laden
34
  STI_PVR   = 0x40;      // Basisadresse der Ints für crt0.s Tabelle setzen
35
36
  __asm            // Mode 2 Interrupt auswählen und Ints einschalten
37
     im 2
38
     ei
39
  __endasm ;
40
41
}

von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> A. K. schrieb:
>> Dass du einen Zweifrontenkrieg gegen Hardware und Compiler kämpfst,
>> das hast du dir selbst zuzuschreiben.
>
> Da der ganze Apparillo nichts weiter ist als anderen in Kreuzworträsel
> und keinen praktischen Nutzen hat außer Denksport und Spass am
> Problemlösen und Gestalten denke ich, dass man das vernachlässigen kann.


Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was 
erklärt und nicht einfach immer vernachlässigen. Das rächt sich:
Das Problem beim Troubleshooting ist, der Trouble shootes back!

>
> Du wirst sicher zugeben müssen, dass da Auge der Ästhetik unten
> stehendes Codebeispiel ohne Augenkrebs zu bekommen anschauen kann. Auf
> jedenFall sicher besser als eine Tabelle voller Nummern, die per djnz
> Schleife in die Ports geschrieben werden. Und wenn ich Lust habe kriegt
> jedes Bit auch noch eine define Zeile....
>
> Welcher Depp ist eigenlich dafür verantwortlich, dass unter Unix und
> Windows cr/lf und lf als Zeilenende unterschiedlich sind?
>

Guckste eventuell mal was eher da war? Ich schätze mal das war die selbe 
stinkreiche Person die meinte das der "wrong slash" (Tm) irnkwie besser 
aussieht...

Gruß,

Holm

BTW: Schnittstelle Locked es gibt da ein einfaches Verfahren mit 
angelegten Lockfiles in einem Directory, die bleiben nach einem Abschuß 
vielfach stehen.

Unter FreeBSD liegen die Standardmäßig unter /var/spool/lock und heißen 
beispielsweise LCK..cuau3. So ein File enthält die Process ID des 
lockenden Prozesses.
$ cat /var/spool/lock/LCK*
      8760
$ $ ps -ax|grep 8760
21337  0  S+        0:00,00 grep 8760
 8760  4  Ss+       0:28,19 seyon -noemulator -modems /dev/cuau3 
-emulator xterm -nodefargs
$

Der LOCKPATH ist unter Looser Unix leicht anders, aber ähnlich.

von (prx) A. K. (prx)


Lesenswert?

Holm Tiffe schrieb:
> Guckste eventuell mal was eher da war? Ich schätze mal das war die selbe
> stinkreiche Person die meinte das der "wrong slash" (Tm) irnkwie besser
> aussieht...

Das kommt aus CP/M, da kann Gates nix für. Der hat bloss ein 
abgekupfertes CP/M für 8088 aufgekauft. Die Programme in CP/M 
verwendeten auch schon "/xxx" für Kommandozeilenoptionen, damit war "/" 
für Pfade weg. Auch die Laufwerksbuchstaben sind aus CP/M.

von Christian J. (Gast)


Lesenswert?

Holm Tiffe schrieb:
> Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was
> erklärt und nicht einfach immer vernachlässigen. Das rächt sich:
> Das Problem beim Troubleshooting ist, der Trouble shootes back!

Und Du musst mal vopn dieser Jogi/Schenk-Denke runterkommen, dass andere 
ihre eigenen Vorstellungen haben und nicht blind das übernehmen, was 
"alte Hasen" meinen richtig sei sonder evtkl lediglich Nuancen oder 
Tendenzen übernehmen. Assembler ist für mich Rummgestammel auf Bitniveau 
mit dem keine komplexen Dinge gescheit zu lösen sind und man 
verschwendet seine Zeit damit. Das wird sich auch nicht mehr ändern.
Dein Wissen ist aber willkommen, vor allem das aus DDR tagen was ich 
sehr interessant fand.

Das mit der /var/loch habe ich mir auch gegoogelt, inzwischen läuft das 
aber problemlos und ich denke, dass ich in ein paar Tagen soweit bin 
Uploads zu machen, wenn noch einiges mehr verkabelt ist und vor allem 
die Dokumentation des Ganzen mal wächst, denn ohne die blicke ich in in 
einigen Monaten nicht mehr durch.

Die Sache mit den Ints ist soweit klar, nur muss ich das noch in die 
Compiler Directiven einarbeiten und rausfinden, wie ich diese Tabelle 
erzeuge. Denn inzwischen ist der Huckepack Sockel vom EEPROM doch schon 
ausgeleiert und es nervt dauernd jede Programmänderung neu zu brennen.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Assembler ist für mich Rummgestammel auf Bitniveau
> mit dem keine komplexen Dinge gescheit zu lösen sind und man
> verschwendet seine Zeit damit. Das wird sich auch nicht mehr ändern.

Das ulkige an dieser bereits hinreichend bekannten Grundeinstellung ist 
freilich, dass du dich trotzdem ausgerechnet in jener Retro-Sphäre 
bewegst, in der man als Assembler-Analphabet ziemlich hilflos ist.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Das ulkige an dieser bereits hinreichend bekannten Grundeinstellung ist
> freilich, dass du dich trotzdem ausgerechnet in jener Retro-Sphäre
> bewegst, in der man als Assembler-Analphabet ziemlich hilflos ist

Amen :-) Ich gehöre auch zu den "Schändern" in deren Röhrenverstärker 
ein Mikroprozessor und ein fertiger Klangnetzwerk-Chip für 
Höhe/Bässe/Balance verbaut sind....Jehova!

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
>> Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was
>> erklärt und nicht einfach immer vernachlässigen. Das rächt sich:
>> Das Problem beim Troubleshooting ist, der Trouble shootes back!
>
> Und Du musst mal vopn dieser Jogi/Schenk-Denke runterkommen, dass andere
> ihre eigenen Vorstellungen haben und nicht blind das übernehmen, was
> "alte Hasen" meinen richtig sei

Seine Anmerkung bezog sich sicherlich nicht nur auf die Weigerung, 
Assembler kennenzulernen. Sondern auch darauf, wie du stur wie ein 
Panzer auf dem komplizierten Weg beharrst und völlig unnötige 
Komplexität ins EPROM einzubaust und dich dabei auch noch mit 
Compiler-Irrwegen abkämpfst, statt ins ROM nur das absolute Minimum 
einzubauen und danach ohne Sockelei im RAM weiterzuarbeiten.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:

> Komplexität ins EPROM einzubaust und dich dabei auch noch mit
> Compiler-Irrwegen abkämpfst, statt ins ROM nur das absolute Minimum
> einzubauen und danach ohne Sockelei im RAM weiterzuarbeiten.

Ist in Arbeit...keep it simple, as simple as possible. Trotzdem dran 
denken, dass es Hobby ist und ein wenig Spielerei dazu gehört.

Schonmal bei Fingers elektrischer Welt vorbei geschaut.... geniale 
Seite, da sind auch Projekte von mir drauf :-)

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Hätte ich das vorher gewusst hätte ich ein Bankswitching eingebaut.
;))))

Tja ist das nun ein Hexenwerk, das zu in HW zu debuggen ?
CS Draht ab
SRAM Huckepack
CS über MUX
Und ein Pioportbit (alternativ kannst du ein HW Handshakepin der SIO... 
liegt eh rum missbrauchen) für den MUX

Glaub mir je, länger du rumpopelst desto länger wird dir das Kopfweh 
machen und du wirst deine Zeit damit vertrödeln neue Krücken zu basten. 
Je eher du das nachrüstest, desto schneller wirst du glücklich mit dem 
was du vorhast.
...

Namaste

: Bearbeitet durch User
von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> Holm Tiffe schrieb:
>> Du mußt Dir unbedingt mal angewöhnen zuzuhören wenn Dir Jemand was
>> erklärt und nicht einfach immer vernachlässigen. Das rächt sich:
>> Das Problem beim Troubleshooting ist, der Trouble shootes back!
>
> Und Du musst mal vopn dieser Jogi/Schenk-Denke runterkommen, dass andere
> ihre eigenen Vorstellungen haben und nicht blind das übernehmen, was
> "alte Hasen" meinen richtig sei sonder evtkl lediglich Nuancen oder
> Tendenzen übernehmen. Assembler ist für mich Rummgestammel auf Bitniveau
> mit dem keine komplexen Dinge gescheit zu lösen sind und man
> verschwendet seine Zeit damit.

Jawoll, da isser wieder uns Krischan...



> Das wird sich auch nicht mehr ändern.

Das Gefühl habe ich auch. IM2 ist sowieso Quatsch und die 8255 ist ein 
Top Teil ..


> Dein Wissen ist aber willkommen, vor allem das aus DDR tagen was ich
> sehr interessant fand.

Ich denke mal Du interessierst Dich für Geschichte die Dir in der Schule 
nicht beigebracht wurde.
Mein Wissen interessiert Dich nicht wirklich, das hast Du gerade eben 
wieder bewiesen.

>
> Das mit der /var/loch

What?

> habe ich mir auch gegoogelt, inzwischen läuft das
> aber problemlos und ich denke, dass ich in ein paar Tagen soweit bin
> Uploads zu machen, wenn noch einiges mehr verkabelt ist und vor allem
> die Dokumentation des Ganzen mal wächst, denn ohne die blicke ich in in
> einigen Monaten nicht mehr durch.
>
> Die Sache mit den Ints ist soweit klar, nur muss ich das noch in die
> Compiler Directiven einarbeiten und rausfinden, wie ich diese Tabelle
> erzeuge. Denn inzwischen ist der Huckepack Sockel vom EEPROM doch schon
> ausgeleiert und es nervt dauernd jede Programmänderung neu zu brennen.

Ich habe mir mein Wissen mit Lesen angeeignet, damit hast Du es wohl 
nicht so. Warum rennst Du immer mit dem Kopf gegen die Wand wenn es 
dunkel ist, anstatt Dich vorsichtig und mit Bedacht an die Wand heran zu 
arbeiten?

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

A. K. schrieb:
> Holm Tiffe schrieb:
>> Guckste eventuell mal was eher da war? Ich schätze mal das war die selbe
>> stinkreiche Person die meinte das der "wrong slash" (Tm) irnkwie besser
>> aussieht...
>
> Das kommt aus CP/M, da kann Gates nix für. Der hat bloss ein
> abgekupfertes CP/M für 8088 aufgekauft. Die Programme in CP/M
> verwendeten auch schon "/xxx" für Kommandozeilenoptionen, damit war "/"
> für Pfade weg. Auch die Laufwerksbuchstaben sind aus CP/M.

Der stinkreiche Arsch hat auch ein Rudel Systemrufe und die Pfade aus 
Unix übernommen die in QDOS nicht drin waren, er hat also entschieden.
Garry kann man keinen Vorwurf machen ,der war ja fliegen..

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> A. K. schrieb:
>> Das ulkige an dieser bereits hinreichend bekannten Grundeinstellung ist
>> freilich, dass du dich trotzdem ausgerechnet in jener Retro-Sphäre
>> bewegst, in der man als Assembler-Analphabet ziemlich hilflos ist
>
> Amen :-) Ich gehöre auch zu den "Schändern" in deren Röhrenverstärker
> ein Mikroprozessor und ein fertiger Klangnetzwerk-Chip für
> Höhe/Bässe/Balance verbaut sind....Jehova!

Jaaa, das Wichtigste aber sind die blauen LEDs.

Christian ein guter Rat:
Lege Dich nicht mit mir an in dem Du versuchst mich zu provozieren. 
Wie das ausgeht weißt Du. Du bist mir rhetorisch nicht gewachsen. Ich 
will das aber nicht wirklich und amüsiere mich derzeit. Laß es also 
dabei, dann behältst Du die Unterhosen an.

Im Ernst, hättest Du nicht alle Ratschläge hier immer wieder in den Wind 
geschlagen, hätte ich mich auch etwas besser um Dich gekümmert. Dein 
Ansatz möglichst in C programmieren zu wollen ist mir auch nicht neu,
ich habe das selbe Problem mit dem 68k nebenan.
Z80 Assembler ist aber einer der einfacheren, die Menmonics sind 
eingängig und gut zu merken, die CPU überschaubar.

Lies doch den Thread einfach nochmal von vorne und analysiere was Du 
alles an Ratschlägen missachtet und dann korreliere mit welchen 
Problemen Du jetzt zu kämpfen hast.
Die Sache mit dem Controller im Röhrenverstärker beeindruckt mich 
wirklich, aber nur dahingehend das Du das als Besonderheit erwähnst. Was 
glaubst Du wohl wie andere Leute Infrarotfernbedienungen realisieren? 
Mit nem Wasserrad und Preßluft? Boah ehy. Die Tatsache das Du 
erfolgreich einen EL84 Verstärker zusammengelötet hast beeindruckt mich 
eher gar nicht. Das habe ich schon vor 40 Jahren gemacht und in der 
Röhrenbude wird das immer für Anfänger empfohlen.

Gruß,

Holm

von S. R. (svenska)


Lesenswert?

Hallo,

> stellt sich dennoch die ein oder andere Frage, da ich mich mit
> Protokollen von Schnittstellen nicht so genau aus kenne.

Das liegt daran, dass du nicht liest, was andere dir schreiben. Oder du 
ignorierst alles bewusst und absichtlich, was gerade außerhalb deiner 
Scheuklappen sitzt und bist gleichzeitig nicht willens, später nochmal 
zurückzublättern.

> Wenn vom PC ein Binärdatenstrom über das USB Interface in die Uart
> reinkommt, wie zeigt dann der PC das Datenende an?

Garnicht, weil Binärdaten das nicht können.

Du sagtest, du arbeitest in einem technischen Bereich? Irgendwie kann 
ich mir das nicht vorstellen, weil du die selben Anfängerfragen immer 
und immer wieder stellst.

> Ich habe nur zwei Leitungen, RX und TX, kein Hardware Flow Control,
> kein Handshake. Daten die kommen müssen entgegen genommen werden
> da sie unentwegt weiterlaufen.

Tja, selbst schuld. Hättest du auch nur ein kleines bisschen vorher 
nachgedacht und ein Protokoll entworfen, wäre das alles kein Problem 
gewesen. Natürlich hättest du eins der vorhandenen Protokolle benutzen 
können, oder sogar die hier genannten Vorschläge benutzen können (Tipp: 
Die sind in diesem Thread immernoch drin!), aber du willst ja 
offensichtlich nicht.

> Kann ich das Datenende nur über Timeout erkennen? Denn die Vereinbarung
> eines speziellen Zeichens geht ja im Binärcode nicht.

Klar kannst du das machen, und unter den angegebenen Bedingungen bleibt 
dir auch keine Alternative. Gibt zwar kaum dümmere Methoden, aber wem 
der Schuh passt...

> Aktuell laufen die Zeichen über den SIO Interrupt rein und füllen einen
> Ringpuffer, der 3/4 "voll" meldet hofft hofft dass das Hauptprogramm
> sich um ihn kümmert bevor Daten verworfen werden.

Wenn ein Ringpuffer ab 75% Füllstand anfängt, Daten wegzuschmeißen, dann 
ist er entweder exakt vier Byte groß oder hochgradig hirnrissig 
implementiert. Es schadet übrigens nicht, in einer Bootstrap-Schleife 
mit Polling zu arbeiten - schließlich hat die CPU ja noch nichts 
besseres zu tun.

> der Compiler spuckt leider nur variable Länge aus und der Binärconverter
> auch.

Sehr überraschend. Ich bin zufrieden, wenn für ein 400 Byte großes 
Programm keine 8 KB übertragen werden müssen. Je nach Geschwindigkeit 
der Schnittstelle dauert das nämlich eine Weile...

> Der Compiler erzeugt keine object files :-(  dd ist sehr praktisch
> da mit bs = 8192 ja die Blockgröße gesetzt werden kann.

Klar erzeugt er Object Files, aber eben keine ELF-Dateien auf *.o, 
sondern Textdateien auf *.rel. Ist halt kein GNU-Compiler.

> Etwas anders wird schon schwieriger.... denn ein Programm im RAM ab
> 0x2000, dem fehlen die ganze Zeropage und da liegen bekanntlich einige
> Vektoren.

Erstens liegen in der Zeropage keine Vektoren, wenn du sie da nicht 
willst (der Z80 ist intelligent genug). Zweitens fehlt die Zeropage 
nicht, sondern enthält das, was du ihr da hingelegt hast. Wenn du das 
ROM nicht wegschaltest, liegt da das ROM.

> Und ich kann ROM nicht nach RAM überblenden, da das darunter
> liegt. D.h. dass zb Int Mode 2 gar nicht möglich ist, denn der würde auf
> das ROM zugreifen und die Vektoren zeigen irgendwo hin aber nicht auf
> die Routinen im RAm da die jedesmal woanders liegen.

Ein Binärformat würde das ohne Probleme lösen. Alternativ eine neue 
Vektortabelle im RAM, die vom Startup-Code durch Änderung des 
I-Registers aktiviert wird. Das ist alles keine Raketentechnologie. Du 
willst Retro, aber irgendwie bist du unwillig, dir auch nur die Lösungen 
anzuschauen, die dir auf dem Silbertablett serviert werden.

> Daran habe ich leider nicht gedacht, dass alles aus der Zeropage jetzt
> unerreichbar ist.

Wieso unerreichbar? Da ist immernoch das, was da vorher auch war. Ob du 
es benutzen willst oder nicht, spielt doch keine Rolle. Es gibt durchaus 
Monitorprogramme mit Funktionen, die ein nachgeschaltetes 
Anwendungsprogramm weiternutzen will - nennt man oft BIOS oder so.

> Auch die Software Interrupts RST n, NMI sowieso,
> alle Timer Interrupts usw.

Die Interrupts kannst du per I-Register im IM2 verlegen. RST n und NMI 
kannst du indirekt nutzen, indem du an die passende Stelle im Monitor 
einfach einen Sprung an eine RAM-Adresse legst... das darf im 
Zweifelsfall auch eine dynamische Adresse sein, die sich aus einem 
Header des Anwendungsprogramms ergibt... ach ne, du willst ja nur rohe 
Binärdaten. Dann geht das natürlich alles nicht.

> Der Compiler lässt es leider nicht zu, dass man Routinen fixe Adressen
> verpasst, der will da sehr frei wählen wo jedes Segment liegt.

Der Compiler ist nicht intelligent genug, um dir das zu verbieten. Wenn 
du ein Symbol passend deklarierst, dann nutzt der das auch. Muss man 
halt nur (in (Inline-)Assembler) machen. Aber auch das willst du ja 
nicht. Dann geht das natürlich auch nicht, da hast du schon recht...

Gruß

von Christian J. (Gast)


Lesenswert?

Holm Tiffe schrieb:
> Lege Dich nicht mit mir an in dem Du versuchst mich zu provozieren.
> Wie das ausgeht weißt Du. Du bist mir rhetorisch nicht gewachsen. Ich
> will das aber nicht wirklich und amüsiere mich derzeit. Laß es also
> dabei, dann behältst Du die Unterhosen an.

@S.R.: Danke für Deine Ausführungen, das Allermeiste hat sich aber 
inzwischen auch so gelöst und hätte nicht diskutiert werden müssen, wenn 
man mal drüber geschlafen hat.

@Holm:

Es mag rund 10 Jahre her sein aber ich sitze da mit einem breiten 
Grinsen, weil ich genau weiss welche Hebel und Knöpfe ich drücken muss, 
damit Du "aufsteigst". Also seien wir lieb, Du bist nämlich ein feiner 
Kerl glaube ich :-)

Ich habe mich erstmal entschieden, dass der reine Upload zu öde ist, da 
der in ein paar Zeilen kodiert ist und mich für eine "Terminal" Umgebung 
entschieden.

Reiner Upload ist mit
echo "U" > /dev/tty
stat -c %s binaer.bin > /dev/tty
cat  binaer.bin > /dev/tty

gemacht, wenn man U als Startzeichen sieht, danach Dateigröße (als 
ascii), dann die Daten und fertig. Timeout ist ebenso legal und einfach, 
wenn man die n-fache Bytezeit bei 9600 als TO deklariert. Das Kopieren 
ins Ram geht nur über inline asm, war auch nicht schwer.

Ich habe bis spät abends gestern Routinen kodiert die es ermöglichen dem 
Z80 System Kommandozeilen zu übergeben. Leider sendet minicom bei 
Tasteneingaben jedes Zeichen einzeln so dass ich im Z80 zb Cursor, ESC, 
BS und DEL abfangen und korrigieren müsste durch Versetzung des Pointers 
im RX Buffer, hterm unter Windows sendet erst bei CR Strings ab. Dafür 
entfällt die Timeout Funktion, da CR das Datenende signalisiert. Das 
Parsen der Strings ist recht einfach.

Ob ein ausführbares Programm im Speicher liegt wird im Startup des 
Monitors erfragt da der erste Befehl ein immer JP xxxx" ist. Dann wird 
das Ausnullen übersprungen und direkt losgelegt, damit ein Reset nicht 
alles löscht.

Von daher werde ich beides in einem Schreiben: Ein Art 
Bediener-Menüführung, zb auch um ein 4 Gewinnt Spiel etc zu spielen 
(printf und scanf arbeiten) aber auch die Möglichkeit per Steuerzeichen 
Uploads und andere Funktionen zu erreichen.

Entgegen meinen Befürchtungen stellt sich die INT Problematik gar nicht, 
auch nicht bei NMI. RST lassen sich umlenken, Mode 2 Ints ja über I 
Register und das Compiler Image arbeitet bei 0x2000 genau wie bei 
0x0000, es ist eben alles nur verschoben und der Offset bekannt.

Aktuell sehe ich nur minicom, screen oder picocom als passendes 
"Terminal", da sind Upload Funktionen bereit halten und andere Dinge.

Es wird schon....

von Christian J. (Gast)


Lesenswert?

Hallo,

da ich dem Rechner(chen) noch etwas mehr einbauen möchte suche ich 
C-Quellcodes von Spielen etc. die sich ausschliesslich printf und scanf, 
bzw puts und gets als Ausgabe bedienen, rein textbasiert sind. Ich habe 
aktuell ein recht starkes 4 gewinnt gegen den Computer aber wenn es ein 
Text Schachprogramm oder Schiffe versenken etc geben würde wäre das auch 
nett.

Kennt da jemand noch etwas?

Gruss,
Christian

von Christian J. (Gast)


Lesenswert?

Noch ein Wort zum sdcc Compiler für den, den es interessiert:

Erfreulichwerweise erlaubt er es Variablen an fixe Plätze im Speicher zu 
legen und vermeidet auch die Prüfung ob diese Variablen mit anderen 
Inhalten des RAM kollidieren. Auf diese Weise lässt sich zb mit

__at 0x2000 char ram[56x1024];

das ganze RAM direkt adressieren (natürlich auch der SP zerschiessen).

Oder Inhalte des ROM mit

__at 0x0 char rom[8192];

rüber kopieren.

Was NICHT geht und das schränkt doch erheblich ein ist es mit inline asm 
lokale Variablen oder Funktionsparameter zu erreichen. Niente, geht 
nicht! Aus dem Grund, weil diese im Stack übergeben werden und die 
Übergabe jedesmal anders ist, man nicht weiss wo sie liegen. Manchmal 
auf im DE oder BC Register. Ein (_variable) gilt nur für globale Werte 
und die sollte man eh vermeiden wo es geht.

Weiterhin klappt es nicht statische Variablen in Funktionen zu 
initialisieren, diese Funktion gibt es (noch) nicht.

von Holm T. (Gast)


Lesenswert?

Das kann so nicht sein wie Du es beschreibst. Ein Compiler hat immer 
calling conventions für Subroutinen und die sind auch nicht jedesmal 
anders, sie richten sich maximal nach der Art der übergebenen Variable.
Ich gehe davon aus das Du die entsprechende Doku einfach nicht gelesen 
hast, Du bist genu so stinkend faul wie ich, abe rwenn man was Konkretes 
wissen will muß man halt dediziert nach den Definitionen suchen, 
manchmal auch im Sourcecode.

Gruß,

Holm

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Was NICHT geht und das schränkt doch erheblich ein ist es mit inline asm
> lokale Variablen oder Funktionsparameter zu erreichen. Niente, geht
> nicht!

Die falschen Behauptungen werden auch durch ständige Wiederholung nicht 
wahr.

> Aus dem Grund, weil diese im Stack übergeben werden und die
> Übergabe jedesmal anders ist, man nicht weiss wo sie liegen.

Parameter werden immer auf dem Stack übergeben, und die Reihenfolge ist 
definiert.

> Manchmal auf im DE oder BC Register.

Von diesen beiden wird eines für lokale Variable verwendet, und das 
findet man in der Doku.

Holm Tiffe schrieb:
> Das kann so nicht sein wie Du es beschreibst. Ein Compiler hat immer
> calling conventions für Subroutinen und die sind auch nicht jedesmal
> anders, sie richten sich maximal nach der Art der übergebenen Variable.
> Ich gehe davon aus das Du die entsprechende Doku einfach nicht gelesen

Die Doku dazu ist zugegebenermaßen sehr dünn. Ausprobieren würde helfen.
Wie das geht ist allerdings für den 8051 sehr ausfürlich mit einer 
"Schritt für Schritt" Anleitung in der Doku beschrieben, ab Kapitel 
"3.14 Inline Assembler Code".

Christian J. schrieb:
> Weiterhin klappt es nicht statische Variablen in Funktionen zu
> initialisieren, diese Funktion gibt es (noch) nicht.

Auch diese Falschbehauptung wurde schon irgendwo widerlegt. Ich finde 
nur die Stelle nicht. Wie man in meinem angehängten Versuch sehen kann, 
erzeugt der Compiler dafür (derzeit) Code in der GSINIT-Area. Ziemlich 
ineffizient, aber geht. Die lokale Variable 'local' liegt hier auch auf 
dem Stack. Den Platz dafür schafft der 'push af' am Anfang der Funktion.

Test:
1
extern int f(int *x);
2
3
int test( int a, int b)
4
{
5
  static int drei = 3;
6
  
7
  int local;
8
  
9
  local = a + b;
10
  
11
  return drei + f(&local);
12
}

Compiler Output:
1
;--------------------------------------------------------
2
; File Created by SDCC : free open source ANSI-C Compiler
3
; Version 3.4.0 #8981 (Jul  5 2014) (Linux)
4
; This file was generated Thu Oct 30 11:39:18 2014
5
;--------------------------------------------------------
6
  .module testpar
7
  .optsdcc -mz80
8
  
9
;--------------------------------------------------------
10
; Public variables in this module
11
;--------------------------------------------------------
12
  .globl _test
13
  .globl _f
14
;--------------------------------------------------------
15
; special function registers
16
;--------------------------------------------------------
17
;--------------------------------------------------------
18
; ram data
19
;--------------------------------------------------------
20
  .area _DATA
21
_test_drei_1_3:
22
  .ds 2
23
;--------------------------------------------------------
24
; ram data
25
;--------------------------------------------------------
26
  .area _INITIALIZED
27
;--------------------------------------------------------
28
; absolute external ram data
29
;--------------------------------------------------------
30
  .area _DABS (ABS)
31
;--------------------------------------------------------
32
; global & static initialisations
33
;--------------------------------------------------------
34
  .area _HOME
35
  .area _GSINIT
36
  .area _GSFINAL
37
  .area _GSINIT
38
;testpar.c:5: static int drei = 3;
39
  ld  iy,#_test_drei_1_3
40
  ld  0 (iy),#0x03
41
  ld  iy,#_test_drei_1_3
42
  ld  1 (iy),#0x00
43
;--------------------------------------------------------
44
; Home
45
;--------------------------------------------------------
46
  .area _HOME
47
  .area _HOME
48
;--------------------------------------------------------
49
; code
50
;--------------------------------------------------------
51
  .area _CODE
52
;testpar.c:3: int test( int a, int b)
53
;  ---------------------------------
54
; Function test
55
; ---------------------------------
56
_test_start::
57
_test:
58
  push  af
59
;testpar.c:9: local = a + b;
60
  ld  hl,#6
61
  add  hl,sp
62
  ld  iy,#4
63
  add  iy,sp
64
  ld  a,0 (iy)
65
  add  a, (hl)
66
  ld  d,a
67
  ld  a,1 (iy)
68
  inc  hl
69
  adc  a, (hl)
70
  ld  e,a
71
  ld  iy,#0
72
  add  iy,sp
73
  ld  0 (iy),d
74
  ld  1 (iy),e
75
;testpar.c:11: return drei + f(&local);
76
  ld  hl,#0x0000
77
  add  hl,sp
78
  push  hl
79
  call  _f
80
  pop  af
81
  ld  de,(_test_drei_1_3)
82
  add  hl,de
83
  pop  af
84
  ret
85
_test_end::
86
  .area _CODE
87
  .area _INITIALIZER
88
  .area _CABS (ABS)

von Eric (Gast)


Lesenswert?

Christian J. schrieb:

    [sdcc]
> Aufpassen muss man allerdings, dass die Debian Repos nur bis zur Version
> 3.0.0 reichen von 2012 und da sind noch eine Menge Bugs drin

Debian testing enthält v3.4.0 
(https://packages.debian.org/testing/electronics/sdcc).
Kann man nicht meckern.

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Aus dem Grund, weil diese im Stack übergeben werden und die
> Übergabe jedesmal anders ist, man nicht weiss wo sie liegen.

Wie schon gesagt werden die Parameter immer gleich übergeben. Der 
Zugriff darauf kann aber je nach Optimierungsmöglichkeiten variieren. 
Einfacher wirds, wenn man den Compiler davon abhält, den Framepointer 
wegzuoptimieren.
Option: --fno-omit-frame-pointer

In dem Zusammenhang meine ich, einen Compiler-Bug gefunden zu haben. Das 
muß ich mir aber erst noch genauer anschauen.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Leo C. schrieb:
> Parameter werden immer auf dem Stack übergeben, und die Reihenfolge ist
> definiert.

Hm, dann sind die Compiler, welche die ersten N Parameter einer Funktion 
auch per Register übergeben können, Teufelswerk?

von Leo C. (rapid)


Lesenswert?

Frank M. schrieb:
> Hm, dann sind die Compiler, welche die ersten N Parameter einer Funktion
> auch per Register übergeben können, Teufelswerk?

Wie kommst Du denn hier auf "Compiler, welche die ersten N Parameter 
einer Funktion auch per Register übergeben können"?

von (prx) A. K. (prx)


Lesenswert?

Ich denke, es geht hier im einen ganz bestimmten Compiler. Da kann es 
schon sein, dass der alle Parameter per Stack übergibt. Das bedeutet 
nicht, dass alle Compiler es so machen.

von Christian J. (Gast)


Lesenswert?

Nabend,

ich schreibe das mir nicht aus den Fingern heraus, daher bitte ich darum 
auf die Frozzeleien zu verzichten.

Ich habe mir den erzeugetn Code (mit Optimierung!) genau angeschaut und 
es ist so, dass er mal auf dem Stack übergibt und mal einfach nur per 
Register! Und darauf verlasse ich mich garantiert nicht, sondern mache 
das mit einem Workaround, idem ich lokale Variablen, die nicht mit 
Symbol erreichbar sind zuerst in eine globale Variable kopiere und mir 
von dort aus hole. Die Doku ist völig unzureichend. da steht nicht mal 
was über die .areas drin.

Bitschiebrei und testen ist in Schleifen per Asm deutlich effizienter, 
sonst ist es egal wenn es nur einmal durchlaufen wird, platz genug ist 
da.

Debian main liefert 3.3.0 derzeit. aktuell ist 3.4.5 und das hat 700 
Bytes Code um ganze 150 Bytes reduziert.  Die letzte Code Änderung fand 
heute statt:

http://sdcc.sourceforge.net/snap.php

Und was static angeht so habe ich die Aussage eines der Programmierer 
dieses Compilers, das das noch nicht ausgereift ist. Ineffizient sowieso 
aber es wäre noch eine Baustelle, die ich nicht benutzen sollte.


@Leo

Welchen ASM Code hast Du denn im Startup unter der area GSINIT stehen? 
Bei mir ist da nur ein ret drin.
1
 ;///////////////////////////////////////////////////////////
2
    ; Anordung der Segmente fuer den Linker, ab hier nur relative
3
    ; Adressen
4
5
      .area  _CODE
6
      .area  _INITIALIZER
7
      .area  _HOME
8
      .area  _GSINIT
9
      .area  _GSFINAL
10
      .area  _DATA
11
      .area  _INITIALIZED
12
      .area  _BSEG
13
      .area  _BSS
14
      .area  _HEAP
15
    
16
    ;///////////////////////////////////////////////////////////
17
    ;; ------- Start des Hauptprogramms nach der Zeropage  -----------
18
    
19
    .area _CODE
20
    init:
21
    
22
    ld  sp,#stack   ;; Stack an Spitze des RAM legen
23
    
24
    ; Teste ob Userprogramm im RAM vorhanden
25
    ; ....
26
    
27
    ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt)
28
    xor     a             ; clear a and carry
29
    ld      bc,#0xdfff    ; ram size left
30
    ld      hl,#0x2000    ; starting from 2000
31
    ld      de,#0x2001
32
    ld      (hl),a        ; 0 -> (2000) 
33
    ldir                  ; (HL) -> (DE)
34
35
    ; Initialisiere globale Variablen im RAM
36
    ld  bc, #l__INITIALIZER
37
    ld  a, b
38
    or  a, c
39
    jr  Z, weiter
40
    ld  de, #s__INITIALIZED
41
    ld  hl, #s__INITIALIZER
42
    ldir
43
44
weiter: 
45
46
    ; ###### Hauptprogramm aufrufen #######
47
    jp  _main       
48
49
    ; Endlos Schleife
50
    halt
51
 endlos:
52
    jr endlos       ; Sicher ist sicher
53
    
54
    ret
55
       
56
          
57
    ; // reserved
58
      .area _GSFINAL
59
      ret

von Leo C. (rapid)


Lesenswert?

Wenn Du nur mit "geheimen" Informationen operierst, kannst Du den Rest 
auch noch für Dich behalten, und mußt nicht das Forum hier belästigen. 
Du stellst hier ständig falsche Behauptungen über sdcc auf, ohne 
irgendwas mit nachvollziehbaren Beispielen zu belegen, so daß sich ein 
sdcc-Entwickler schon genötigt sieht, hier eine ganze Artikelserie mit 
Klarstellungen zu posten. Und wenn man versucht Dir auf die Sprünge zu 
helfen, wirst Du auch noch pampig.

von Christian J. (Gast)


Lesenswert?

Seitenweise Bit für Bit:

Beitrag "Mehrdimensionale char-arrays"

"Du brauchst dann, später noch den Sprung nach gsinit, da leider die
Initalisierung mit _INITIALIZER / _INITALIZED zur Zeit nur für globale
Variablen funktioniert. Der _GSINIT-Mechanismus wird noch für lokale
Variablen mit storage class static gebraucht."

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Ich habe mir den erzeugetn Code (mit Optimierung!) genau angeschaut und
> es ist so, dass er mal auf dem Stack übergibt und mal einfach nur per
> Register!

Hast du da ein konkretes Beispiel?

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Ich habe mir den erzeugetn Code (mit Optimierung!) genau angeschaut und
> es ist so, dass er mal auf dem Stack übergibt und mal einfach nur per
> Register!

Wo sind Deine Beispiele (C-Source und Compiler Output (.asm))?

Christian J. schrieb:
> Welchen ASM Code hast Du denn im Startup unter der area GSINIT stehen?
> Bei mir ist da nur ein ret drin.

hier:
Leo C. schrieb:
> ;--------------------------------------------------------
> ; global & static initialisations
> ;--------------------------------------------------------
>   .area _HOME
>   .area _GSINIT
>   .area _GSFINAL
>   .area _GSINIT
> ;testpar.c:5: static int drei = 3;
>   ld  iy,#_test_drei_1_3
>   ld  0 (iy),#0x03
>   ld  iy,#_test_drei_1_3
>   ld  1 (iy),#0x00


Wenn ich das richtig sehe, hast Du oben Deine crt0.s gepostet. Da kann 
der Initialsierungscode einer Funktion, die in einer anderen Datei steht 
natürlich nicht drin sein. In der crt0.s muß allerdings Code sein, der 
den Code in GSINIT aufruft.

Christian J. schrieb:
> Und was static angeht so habe ich die Aussage eines der Programmierer
> dieses Compilers,

Zeigen! (link)

> das das noch nicht ausgereift ist.

Ich habe ja auch nichts anderes behauptet. Du behauptest aber, lokale 
statische Variablen würden überhaupt nicht initialisiert.

> Ineffizient sowieso aber es wäre noch eine Baustelle, die ich nicht
> benutzen sollte.

Wenn man nichts effizientes hat, muß man eben mit dem ineffizienten 
Vorlieb nehmen. Funktionieren tut es ja.

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:
> Zeigen! (link)

s.o.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Leo C. schrieb:
>> Zeigen! (link)
>
> s.o.

So wird das nichts. Bitte konkret, nicht als summarischen Link auf 
einen sich über 8 Jahre erstreckenden Thread. Und bitte auch nicht als 
summarischen Verweis auf diesen sich über 4 Seiten erstreckenden Thread.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Version 1:
1
;driver.c:49: void printstrng(char *k)
2
                            340 ;  ---------------------------------
3
                            341 ; Function printstrng
4
                            342 ; ---------------------------------
5
   01BD                     343 _printstrng_start::
6
   01BD                     344 _printstrng:
7
                            345 ;driver.c:51: while ((*k) != '\0')        
8
   01BD C1            [10]  346   pop  bc
9
   01BE E1            [10]  347   pop  hl
10
   01BF E5            [11]  348   push  hl
11
   01C0 C5            [11]  349   push  bc
12
   01C1                     350 00101$:
13
   01C1 7E            [ 7]  351   ld  a,(hl)
14
   01C2 B7            [ 4]  352   or  a, a
15
   01C3 C8            [11]  353   ret  Z

Version 2:
1
;  ---------------------------------
2
                            367 ; Function SetDigit
3
                            368 ; ---------------------------------
4
   01D0                     369 _SetDigit_start::
5
   01D0                     370 _SetDigit:
6
                            371 ;driver.c:61: SEG7 = digits[i & 0x0f];
7
   01D0 21 02 00      [10]  372   ld  hl, #2+0
8
   01D3 39            [11]  373   add  hl, sp
9
   01D4 7E            [ 7]  374   ld  a, (hl)
10
   01D5 E6 0F         [ 7]  375   and  a, #0x0F
11
   01D7 5F            [ 4]  376   ld  e,a
12
   01D8 21r5Cr00      [10]  377   ld  hl,#_digits

Die Registervariante hatte ich auch mal in den Fingern aber ichfinde sie 
nicht mehr, da ich seitdem was verändert habe.

Ist mir trotzdem zu undurchschaubar, daher "Workaround".

Nur zum Verständnis: static heisst "Nur bei Programmstart", nicht bei 
jedem Aufruf der Routine.

von (prx) A. K. (prx)


Lesenswert?

Version 1 hatten wir doch schon mal. Da wird keineswegs per Register 
übergeben, wie ich an dieser Stelle auch deutlich beschrieb.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> So wird das nichts. Bitte konkret, nicht als summarischen Link auf
> einen sich über 8 Jahre erstreckenden Thread

Die letzten 30 oder 40 Beiträge handeln nur von diesem Thema "Variablen" 
in diesem Thread, weil das bis aufs letzte Bit auseinander genommen 
wurde, wie da was organsiert ist.

Gute Nacht!

Beispiel "Segment Problem", ob behoben weiss ich nicht.

http://comments.gmane.org/gmane.comp.compilers.sdcc.user/2405

Hi,

When I use my custom crt0, in the final binary, gsinit: is pointing to
GSFINAL instead of GSINIT. Therefore, global variables do not get
initialised. Also, GSINIT is placed into DATA which seems to be wrong.
Finally, since my device only has RAM and not ROM, I don't think I
need separate CODE and DATA areas - all variables can be stored in
CODE like consts are. Is there some way to tell the compiler to do
that?

von (prx) A. K. (prx)


Lesenswert?

A. K. schrieb:
> wie ich an dieser Stelle auch deutlich beschrieb.

... und wieder gelöscht hatte, nachdem ich sah, dass KHB sich bereits 
korrigiert hatte. Jedenfalls kriegt _printstrng seinen Parameter völlig 
korrekt auf dem Stack und ins richtige Register.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Ok...

es gibt wie man sieht aber verschiedene Wege, über push/pop und über 
Indexierung einer Stack Adresse mit IY, bzw. die gehört auch noch dazu. 
Oben ist es ja über HL + Offset + SP.

und wie ermittelt man dann die korr. Position auf dem Stack? Bzw finde 
ich derzeit noch meine Lösung mit dem zeitweisen Umkopieren auf global 
praktiklabler, da ich nicht im Stack fummeln muss und zudem symbolische 
Namen habe, auf die einfach zuzugreifen ist.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> und wie ermittelt man dann die korr. Position auf dem Stack?

Am Anfang der Funktion gilt:
SP+0: Return-Adresse.
SP+2: Erster Parameter.

Wie es danach weiter geht hängt von den Parametern und dem ABI ab. 
Vermutlich werden pro Parameter mindestens 2 Bytes fällig.

Etwaige Veränderungen an SP innerhalb der Funktion müssen natürlich 
eingerechnet werden, wenn man SP als Basis der Adressierung verwendet.

Je nach Compiler, Optionen und Laune kann es auch einen Frame-Pointer 
geben, hier wohl IY, der im Unterschied zum SP innerhalb einer Funktion 
unverändert bleibt und als Basis der Adressierung lokaler Daten und 
Parameter dient.

Deine beiden vorhin gezeigten Beispiele greifen beide auf SP+2 zu, nur 
auf höchst unterschiedliche Weise. Variante 1 poppt beide Worte vom 
Stack und schiebt sie sofort wieder zurück, Variante 2 rechnet SP+2 aus 
und fischt sich das indirekt von dort.

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

A. K. schrieb:
> Je nach Compiler, Optionen und Laune kann es auch einen Frame-Pointer
> geben, hier wohl IY,

Witziger Weise nimmt er IX als Framepointer, wenn man ihm per Option 
sagt, daß er den Framepointer nicht weglassen darf.

> der im Unterschied zum SP innerhalb einer Funktion
> unverändert bleibt und als Basis der Adressierung lokaler Daten und
> Parameter dient.

Der Preis für die größere Übersichtlichkeit ist, daß für jeden 
Funktionsaufruf 2 Byte zusätzlich auf dem Stack gebraucht werden, da der 
aktuelle Framepointer gerettet werden muß.

Hier mal ein Beispiel
1
extern int f(int *x);
2
3
int test(int pa, int pb)
4
{
5
  int local;
6
  
7
  local = pa*2 + pb;
8
  
9
  return f(&local);
10
}

Compiliert mit:
$ sdcc -mz80 -S testpar.c --fno-omit-frame-pointer
1
        .area _CODE
2
;testpar.c:3: int test(int pa, int pb)
3
;       ---------------------------------
4
; Function test
5
; ---------------------------------
6
_test_start::
7
_test:
8
        push    ix              ;framepointer (fp) der aufrufenden Funktion retten
9
        ld      ix,#0           ;
10
        add     ix,sp           ;ix mit stackpointer laden (neuer fp)
11
        push    af              ;Platz auf Stack für lokale Variable 'local'
12
13
;Der Stack sieht jetzt so aus:
14
;
15
;       |          | höhere Adressen
16
;       +----------+
17
;       | pb       | sp+8    ix+6
18
;       +----------+
19
;       | pa       | sp+6    ix+4
20
;       +----------+
21
;       | ret-addr | sp+4    ix+2
22
;       +----------+
23
;       | ix       | sp+2    ix+0
24
;       +----------+
25
;       | local    | sp+0    ix-2
26
;       +----------+
27
;       |          | Niedrigere Adressen
28
;
29
30
;testpar.c:7: local = pa*2 + pb;
31
        ld      l,4 (ix)        ;pa nach hl
32
        ld      h,5 (ix)
33
        add     hl, hl          ;pa*2
34
        ld      e,6 (ix)        ;pb nach de
35
        ld      d,7 (ix)
36
        add     hl,de           ;pa*2 + pb
37
        inc     sp              ;sp auf 'local' zeigen lassen
38
        inc     sp              ;trotz fp, so gehts schneller
39
        push    hl              ;hl in 'local' speichern
40
;testpar.c:9: return f(&local);
41
        ld      hl,#0x0000
42
        add     hl,sp           ;addresse von local
43
        push    hl              ;auf Stack als Parameter für f
44
        call    _f
45
        ld      sp,ix           ;locale Variablen vom Stack entfernen
46
        pop     ix              ;fp der aufrufenden Funktion wiederherstellen
47
        ret
48
_test_end::

Wenn man dieses Beispiel ohne Framepointer compiliert, wird beim Laden 
des 2. Parameters das Zwischenergebnis in hl teilweise zerstört. (sdcc 
3.4.0) :(

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> und wie ermittelt man dann die korr. Position auf dem Stack?

Zitat sdcc-Manual:
1
3.14.2 A Step by Step Introduction
2
3
Starting from a small snippet of c-code this example shows for the MCS51 how to use inline assembly, access
4
variables, a function parameter and an array in xdata memory. The example uses an MCS51 here but is easily
5
adapted for other architectures. This is a buffer routine which should be optimized:

Wenn Du Inline-Assembler verwenden willst, wirst Du ums Lernen von 
Assembler nicht herum kommen.

von (prx) A. K. (prx)


Lesenswert?

Leo C. schrieb:
>> geben, hier wohl IY,
>
> Witziger Weise nimmt er IX als Framepointer, wenn man ihm per Option
> sagt, daß er den Framepointer nicht weglassen darf.

Ich hatte IY von Christians Aussage übernommen. Dass es eines dieser 
beiden Register sein würde lag nahe, nur offen welches.

Framepointer waren in früheren C Compilern ziemlich üblich. Da waren 
Compiler noch recht schematisch, ohne statementübergreifende Optimierung 
und mit Registerverwaltung durch den Anwender (Keyword "register").

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

A. K. schrieb:
> Ich hatte IY von Christians Aussage übernommen. Dass es eines dieser
> beiden Register sein würde lag nahe, nur offen welches.

Deswegen witzigerweise. Ohne Framepointer nimmt er IY, wenn er mit HL 
nicht auskommt. Wenn man dann das hier im Handbuch sieht:
1
--reserve-regs-iy 
2
This option tells the compiler that it is not allowed to use register pair 
3
iy. The option can be useful for systems where iy is reserved for the OS. 
4
This option is incompatible with --fomit-frame-pointer.
glaubt man erst recht, daß IY der Framepointer sei.

Mit der Option "--fno-omit-frame-pointer" nimmt er aber konsequent IX.

von (prx) A. K. (prx)


Lesenswert?

Nimmt er IY dann als einmalig in der Funktion definierten echten 
Framepointer? Oder als normales transientes Adressregister, als Ersatz 
für das grad nicht verfügbare HL?

von Leo C. (rapid)


Lesenswert?

Letzteres

von (prx) A. K. (prx)


Lesenswert?

Dachte ich es mir doch. HL ist sowas wie ein 16-Bit Akkumulator. Der 
kann nicht immer auch als Adressregister operieren und ein ADD BC/DE,SP 
gibt es nicht. Also muss IY dran glauben. Völlig normales 
Registermanagement.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Danke, damit kann ich schon was anfangen und mit Asm bin ich ja sowieso 
dabei, allerdings macht hier Übung der Meister, bis man nicht mehr alles 
nachschauen muss, zb was indirekte Adressierung angeht usw.

Ich habe es bei PC und auch 8085 damals wo ich nur Asm programmierte 
immer vermieden den Stack zu manipulieren, da ich den als vom System 
verwaltet ansah und auch Ints, die mir "dazwischen" funken als riskant 
ansah. Nur zwischendurch wenn registerknappheit herrscht mal eben was 
weg gepoppt und danach wieder geholt. Dieses Prinzip Framepointer 
unterstützt Rekursion und verschachtelte Aufrufe wurde auch wohl deshalb 
eingeführt.

Dann werkeln wir mal weiter......

von Leo C. (rapid)


Angehängte Dateien:

Lesenswert?

Nachtrag zu:
Leo C. schrieb:
> Letzteres

Sieht man auch in diesem Beitrag:
Beitrag "Re: Retro Fieber: Z80 oder 68000 ?"

IY wird hier im Gegensatz zum "echten" Frampointer auch nicht auf den 
Stack gesichert.


Christian J. schrieb:
> Beitrag "Mehrdimensionale char-arrays"

Das war die Stelle, die ich hier meinte:

Leo C. schrieb:
> Christian J. schrieb:
>> Weiterhin klappt es nicht statische Variablen in Funktionen zu
>> initialisieren, diese Funktion gibt es (noch) nicht.
>
> Auch diese Falschbehauptung wurde schon irgendwo widerlegt. Ich finde
> nur die Stelle nicht. Wie man in meinem angehängten Versuch sehen kann,

Auf die Idee, in uralten gekaperten Threads zu suchen, kommt man halt 
nicht.

Aber es funktioniert. Zugegebenermaßen etwas tricky. Wichtig ist, das 
man die C-Dateien getrennt kompiliert, und beim Linken die crt0.rel 
zuerst kommt, da darin die Reihenfolge der Segmente definiert ist. 
Außerdem darf man beim Linken die Optionen --code-loc und evtl. 
--data-loc nicht weglassen, sonst werden Segmente übereinander statt 
hintereinander gelegt. Es kommt dann nicht mal eine Fehlermeldung.

Gestern Abend habe ich das mal ausprobiert. D.h. ich habe ein komplett 
lauffähiges Demo erstellt. Zum Testen bin ich aber gestern nicht mehr 
gekommen, weil "mein" Debugger leider auch noch ein paar Ecken hat.

Jetzt gehts aber. Im Anhang ist das komplette Beispiel incl. Makefile, 
daß Du auch für Dein Projekt verwenden kannst.

Die crt0 habe ich auf das für mich absolut notwendige reduziert. Die 
(ABS) Area braucht man im Grunde nicht, auch nicht, wenn das Programm ab 
0 im EPROM laufen soll. Man linkt dann einfach mit '--code-loc 0', bzw 
'CODE_LOC := 0' im Makefile. Die Restart-Vektoren und den NMI-Vektor 
könnte man dann nach dem 'JP init' auch noch platzieren.

Schau Dir das mal an, und vor allem: probier's aus. Schreib Dir dazu 
eine eigene, einfache putchar(). Dazu brauchst Du nicht mal 
Inline-Assembler und erst recht keine Interrupts.
ungefähr so:
void putchar(char c)
{
  while ((sti_statusregister & TX_ready_maske) == 0)
    ; /* warten */
  sti_senderegister = c;
}

von Leo C. (rapid)


Lesenswert?

Noch ein paar Ergänzungen.

Das Beispiel sollte zeigen, daß die Initialisierung von lokalen static 
Variablen funktioniert. Deshalb ist count in main() static deklariert.

putchar() ist __naked deklariert, damit der Assemblercode den Parameter 
c auf dem Stack findet, unabhängig davon, ob mit oder ohne Framepointer 
compiliert wird. Ohne __naked und mit Framepointer würde der Compiler 
diesen Prolog generieren:
1
 push  ix
2
 ld    ix,#0
3
 add   ix,sp
Und dann wäre der Offset zu c nicht mehr 2 sondern 4.
Schön wäre ein Compiler-Macro, daß den Zustand dieses Compilerschalters 
liefern würde, habe ich aber nicht gefunden.

Headerdatei zu myputchar.c habe ich weggelassen, und statt dessen 
stdio.h included. Damit ist sichergestellt, daß der Prototyp von 
putchar() zur libc paßt.

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:

> Aber es funktioniert. Zugegebenermaßen etwas tricky. Wichtig ist, das
> man die C-Dateien getrennt kompiliert, und beim Linken die crt0.rel
> zuerst kommt, da darin die Reihenfolge der Segmente definiert ist.
> Außerdem darf man beim Linken die Optionen --code-loc und evtl.
> --data-loc nicht weglassen, sonst werden Segmente übereinander statt
> hintereinander gelegt. Es kommt dann nicht mal eine Fehlermeldung.

Hi,

da bin ich schon länger, dass man es so machen muss:
1
# Assembliere das crt0 startup file
2
echo "Assembliere....."
3
sdasz80 -plosgff -o -l crt0.rel crt0.s
4
echo "Kompiliere main.c...."
5
sdcc -mz80 main.c -c
6
echo "Linke beide Dateien...."
7
sdcc -mz80 --verbose --no-std-crt0 --vc --code-loc 0x0100 --data-loc 0x2000 crt0.rel main.rel
8
# In Binaerformazt wandeln
9
./hex2bin -p 0 crt0.ihx
10
#echo "Datei zum Target uebertragen..."
11
#cat crt0.bin > /dev/ttyUSB0
1
/////////////////////////////////////////////////////////
2
// Zeichenausgabe für printf auf der STI mit 9600 Baud
3
void putchar(char c)
4
{
5
    while ((STI_TSR & 0x80) == 0);  // Warte bis Buffer frei...
6
    STI_UDR = c;                    // Byte einschreiben
7
8
}

putchar funktioniert schon, getchar auch.

Die Files schaue ich mir mal heute abend in Ruhe an.

gruss,
Christian

von Leo C. (rapid)


Angehängte Dateien:

Lesenswert?

Christian J. schrieb:
> und mit Asm bin ich ja sowieso
> dabei, allerdings macht hier Übung der Meister, bis man nicht mehr alles
> nachschauen muss, zb was indirekte Adressierung angeht usw.

Hier ist eine Gedächtnisstütze.
Das Ding stammt aus einer mc von 1982 und war damals sehr hilfreich. 
Ausgegraben habe ich es wieder, als wir für den AVR-CP/M-Computer den 
Z80-Interpreter gebaut haben. Danach habe ich zwischendurch immer mal 
wieder einen Block davon eingetippt. Nur die Farbe hat immer noch 
gefehlt. Bis heute.

Auch wenn man heutzutage wohl selten die Opcodes eintippt, als 
Übersicht, welcher Befehl mit welchen Operanden funktioniert, und ob und 
wie die Flags beeinflusst werden, ist das "Poster" immer noch gut zu 
gebrauchen.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Danke aber auch das habe ich schon... in bunt ist aber cool, gleich mal 
ausgedruckt.

von Christian J. (Gast)


Lesenswert?

Das geht bei mir nicht!

Wenn gsinit in der Area _GSINIT liegt wird ein Sprung ins Ram erzeugt wo 
nichts ist. Ich habe ewig dazu gebraucht das rauszu finden. gsinti 
daherin die Code Area übernommen und den Call weg gemacht

Daanke für das makefile... ist nicht so meine Welt sowas. Baue ich noch 
ein.

geht nicht:
1
    ;; Initialise global variables
2
        call    gsinit
3
  call  _main
4
  jp  _exit
5
6
  .area   _CODE
7
_exit::
8
  ;; Exit - ddtz breakpoint entry
9
  rst     0x30
10
1$:
11
  halt
12
  jr  1$
13
14
  .area   _GSINIT
15
gsinit::
16
  ld  bc, #l__INITIALIZER
17
  ld  a, b
18
  or  a, c
19
  jr  Z, gsinit_next
20
  ld  de, #s__INITIALIZED
21
  ld  hl, #s__INITIALIZER
22
  ldir
23
gsinit_next:

geht:
1
  ;///////////////////////////////////////////////////////////
2
    ;; ------- Start des Hauptprogramms nach der Zeropage  -----------
3
    
4
    .area _CODE
5
    init:
6
    
7
    ld  sp,#stack   ;; Stack an Spitze des RAM legen
8
    
9
    ; Teste ob Userprogramm im RAM vorhanden
10
    ; ....
11
    
12
    ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt)
13
    xor     a             ; clear a and carry
14
    ld      bc,#0xdfff    ; ram size left
15
    ld      hl,#0x2000    ; starting from 2000
16
    ld      de,#0x2001
17
    ld      (hl),a        ; 0 -> (2000) 
18
    ldir                  ; (HL) -> (DE)
19
20
    ; Initialisiere globale Variablen im RAM
21
    ld  bc, #l__INITIALIZER
22
    ld  a, b
23
    or  a, c
24
    jr  Z, weiter
25
    ld  de, #s__INITIALIZED
26
    ld  hl, #s__INITIALIZER
27
    ldir
28
29
weiter: 
30
31
    ; ###### Hauptprogramm aufrufen #######
32
    jp  _main       
33
34
    ; Endlos Schleife
35
    halt
36
 endlos:
37
    jr endlos       ; Sicher ist sicher
38
    halt
39
          
40
    ; // Hier muss ein ret rein  
41
      .area _GSFINAL
42
      ret

von Leo C. (rapid)


Lesenswert?

> Das geht bei mir nicht!

Dann poste mal die komplette crt0.s (als Anhang)

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Danke aber auch das habe ich schon...

Dann weißt Du ja jetzt, wo Matthias Buchhorn die Seiten 7 bis 9 
abgekupfert hat. ;) Allerdings hat er für die Schiebebefehle noch 
Graphiken zugefügt. Mal sehen, ob ich die auch noch rein bekomme.

> in bunt ist aber cool, gleich mal ausgedruckt.

Und dann die beiden Seiten in eine Klarsichthülle, zum leichten Greifen 
und Wenden. Besser als 11 Seiten, die man blättern muß.

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Leo C. schrieb:
> Dann poste mal die komplette crt0.s (als Anhang)

s. Anhang.

es funktioniert nur so, da sonst der CD (gsinit) eine RAM Adresse 
zugeordnet bekommrt, weil die ganze Area _GSINIT dem RAM Bereich 
zugeordnet wird aus dem --data-loc Wort des Aufrufes. Die Area kann über 
den Linker sdld - .... auf einen Wert gefixt werden aber es gibt kein 
Beispiel und die Man Page ist kryptisch.  Ich habe den Linker nicht 
benutzt sondern lasse das über sdcc erledigen.

btw Manual: Ich habe noch nie ein Variable "c;" allein gesehen. Keine 
Ahnung was das soll.
1
void to_buffer( unsigned char c )
2
{
3
c; // to avoid warning: unreferenced function argument
4
__asm
5
; save used registers here.
6
; If we were still using r2,r3 we would have to push them here.

Da Du dich ja so gut auskennst, wie würde ein Preprozessor Makro in C 
aussehen was mir alle register Pop't und eines was alle Push'ed. 
Mehrzilige makros habe ich noch nicht benutzt und kenne die Syntax auch 
nicht.

von S. R. (svenska)


Lesenswert?

> btw Manual: Ich habe noch nie ein Variable "c;" allein gesehen. Keine
> Ahnung was das soll.

Ich kenne das nur in der Variante "(void)variable;". Das sagt dem 
Compiler, dass diese Variable benutzt wird und nicht wegoptimiert werden 
darf. Damit fällt eine Warnung weg, wenn man eine Variable z.B. nur in 
Inline-Asm benutzt.

von Christian J. (Gast)


Lesenswert?

Hallo,

Bleibt eigentlich noch zu klären warum  RST7 die gleiche Adresse 0x38 
hat wie der Mode 1 Interrupt, den ich mal ausprobiert habe und der auch 
gut funktioniert.

Die crt0.s fasse ich soweit nicht mehr an, da jetzt einschliesslich 
aller Fehlerabfangmechanismen das Ding läuft und genau das tut, was es 
soll. Da habe ich mir mich philipp Krause, der an dem sdcc mitwirkt 
einen Worlf diskutiert wo nun welches Segment steht und in welcher 
Reihenfolge das alles sein muss. Da kommt man nämlich nie drauf, wenn 
man nicht in jede Falle reinlief.

Grundsätzlich ist alles nach dem ersten .area "relativ" zu sehen und 
kein .org darf da mehr stehen, es sei denn man definiert die .area (ABS) 
als absolut und teilt dem Linker mit wohin er sie zu legen hat, was 
wiederum nicht dokumentiert ist und die Syntax dazu Raterei ist. Mit 
--data-loc und --code-loc ist soweit alles gesagt, dass er weiss wohin 
es kommt, klar zwischen  ROM Code und RAM unterscheidet.

      ------ ROM Start --code-loc= 0x100 ------
      .area  _CODE
      .area  _INITIALIZER
      .area  _HOME
      .area  _GSINIT
      .area  _GSFINAL
      ------------ROM Ende = RAM Start 0x2000 ---------
      .area  _DATA
      .area  _INITIALIZED
      .area  _BSEG
      .area  _BSS
      .area  _HEAP

Demzufolge müsste GSINIT eigentlich ins ROM zeigen aber alles was ich da 
reinschreibe landet mit Bezug zum RAM .... rätsel.

Das "Kerlchen" spielt schon ganz prima, säuft Sprit, ähm Strom wie ein 
LKW und es macht Spass mal was anderes als nur einen Controller zu 
haben, der plug & play funktioniert und dank Arduino von jedem Schulkind 
zu bedienen ist.

von (prx) A. K. (prx)


Lesenswert?

S. R. schrieb:
> Ich kenne das nur in der Variante "(void)variable;". Das sagt dem
> Compiler, dass diese Variable benutzt wird und nicht wegoptimiert werden
> darf. Damit fällt eine Warnung weg, wenn man eine Variable z.B. nur in
> Inline-Asm benutzt.

Eigentlich ist das eher ein Hinweis an Compiler und sich selbst, dass es 
Absicht ist, und kein Versehen. Inhaltlich ergibt das m.E. keinen 
Unterschied.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Bleibt eigentlich noch zu klären warum  RST7 die gleiche Adresse 0x38
> hat wie der Mode 1 Interrupt

Weil Zilog zu faul war, es anders zu machen. ;-)

IM0 liest im IACK einen Befehl vom Bus. Wie 8080. Exakt deshalb gibt es 
überhaupt die RST Befehle, damit das ohne grossem Aufwand in einem Byte 
geht.

IM1 tut genau das gleiche wie IM0, kriegt aber statt dessen 0xFF = RST7. 
IM1 springt also nicht wirklich nach 0x38, sondern führt RST7 aus.

: Bearbeitet durch User
von Leo C. (rapid)


Angehängte Dateien:

Lesenswert?

Christian J. schrieb:
> Das geht bei mir nicht!
> Wenn gsinit in der Area _GSINIT liegt wird ein Sprung ins Ram erzeugt wo
> nichts ist.

(Kein Sprung, sondern ein Call, der auch wieder zurückkommen soll.)
In dem Fall wurde die GSINIT-Area ins RAM gelegt was natürlich nicht 
sein sollte.
Das Problem hatte ich auch mal. Ca. 2 Wochen her, und dann hatte ich das 
nicht mehr weiter verfolgt. Die alte crt0.s habe ich nicht mehr. Könnte 
sein, daß ich beim Linken crt0 am Schluß statt am Anfang hatte.

Christian J. schrieb:
> Die crt0.s fasse ich soweit nicht mehr an, da jetzt einschliesslich
> aller Fehlerabfangmechanismen das Ding läuft und genau das tut, was es
> soll.

Es tut bei Dir eben nicht was es soll. Die statischen lokalen Variablen 
werden nicht initialisiert, und irgendwann behauptest Du wieder, das 
wäre ein Fehler von sdcc. Außerdem hast Du mir vorhin per Mail 
geschrieben, daß Du Fehler eben nicht abfangen willst. Deine 
"Mechanismen" sind wirkungslos oder verschleiern sorgar Fehler. 
Hoffnungslos.

Für anderen, die hier noch mitlesen..

Christians crt0.s habe ich so (zurück) geändert, das die Initialisierung 
der globalen Variablen wieder im Unterprogramm gsinit in der Area 
_GSINIT liegt. Seine Interruptvektoren habe ich durch Platzhalter 
ersetzt, sonst habe ich nichts verändert. Ich kann diese Datei mit 
meinem Testprogramm von weiter oben linken, und alles liegt am richtigen 
Platz.

crt0.rst
1
                            138     .area _CODE
2
   0100                     139 init:
3
                            140     
4
   0100 31 FF FF      [10]  141     ld  sp,#stack   ;; Stack an Spitze des RAM legen
...
1
                            154     ;; Initialise global variables
2
   0110 CD 72 0C      [17]  155     call gsinit
3
                            156 
4
                            157     ; ###### Hauptprogramm aufrufen #######
5
   0113 C3 1A 01      [10]  158     jp  _main       
6
                            159 
7
                            160     ; Endlos Schleife
8
   0116 76            [ 4]  161     halt
9
   0117                     162  endlos:
10
   0117 18 FE         [12]  163     jr endlos       ; Sicher ist sicher
11
                            164     
12
   0119 C9            [10]  165     ret
13
                            166        
14
                            167     ; Initialisiere globale Variablen im RAM
15
                            168     .area   _GSINIT
16
   0C72                     169 gsinit::
17
   0C72 01 02 00      [10]  170     ld  bc, #l__INITIALIZER
18
   0C75 78            [ 4]  171     ld  a, b
19
   0C76 B1            [ 4]  172     or  a, c
20
   0C77 28 08         [12]  173     jr  Z, weiter
21
   0C79 11 02 20      [10]  174     ld  de, #s__INITIALIZED
22
   0C7C 21 70 0C      [10]  175     ld  hl, #s__INITIALIZER
23
   0C7F ED B0         [21]  176     ldir
24
   0C81                     177 weiter:
25
                            178 
26
                            179     ;****************************************
27
                            180     ; hier wird der Initialisierungscode für 
28
                            181     ; statische funktionslokole eingefügt
29
                            182     ;****************************************
30
                            183           
31
                            184     ; // Hier muss ein ret rein  
32
                            185       .area _GSFINAL
33
   0C91 C9            [10]  186       ret
Liegt alles im ROM.

hallo_static.rst:
1
;--------------------------------------------------------
2
                             36 ; global & static initialisations
3
                             37 ;--------------------------------------------------------
4
                             38   .area _HOME
5
                             39   .area _GSINIT
6
                             40   .area _GSFINAL
7
                             41   .area _GSINIT
8
                             42 ;hallo-static.c:8: static int count = 5;
9
                             43 ;  genAssign
10
                             44 ;fetchLitPair
11
   0C81 FD 21 00 20   [14]   45   ld  iy,#_main_count_1_13
12
   0C85 FD 36 00 05   [19]   46   ld  0 (iy),#0x05
13
                             47 ;fetchLitPair
14
   0C89 FD 21 00 20   [14]   48   ld  iy,#_main_count_1_13
15
   0C8D FD 36 01 00   [19]   49   ld  1 (iy),#0x00
Wie man sieht, wird der Initialisierungscode aus hallo_static in _GSINIT 
am Ende angehängt. Nach allen Initialisierungsabschnitten der C-Dateien 
(hier gibts nur den einen), kommt die GSFINAL-Area mit dem ret-Befehl.

Die rst-Dateien erzeugt übrigens der Linker bei gesetztem Schalter '-u'. 
Er setzt dann in die lst-Dateien des Compilers die aufgelösten Adressen 
ein.

Im Anhang ist das ganze "Projekt", mit den vollständigen Dateien.

von Leo C. (rapid)


Lesenswert?

A. K. schrieb:
> IM1 tut genau das gleiche wie IM0, kriegt aber statt dessen 0xFF = RST7.
> IM1 springt also nicht wirklich nach 0x38, sondern führt RST7 aus.

Eben, die waren nicht zu faul, sondern haben es faulen Entwicklern noch 
einfacher gemacht.

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> wie würde ein Preprozessor Makro in C
> aussehen was mir alle register Pop't und eines was alle Push'ed.

Wozu soll das gut sein? Im Inline-Assembler braucht braucht man die 
Register des Aufrufers nicht zu retten. Wenn Du da soviel Code 
reinschreibst, daß Du Deine eigenen Zwischenstände retten mußt, machst 
Du irgendwas falsch.

Blieben noch Interrupt-Service-Routinen, die __naked deklariert sind. So 
viele können das nicht sein. Etwas copy-and-paste ist da sicher keine 
Zumutung.

> Mehrzeilige makros habe ich noch nicht benutzt und kenne die Syntax auch
> nicht.

Es gibt keine mehrzeiligen Makros. Aber man kann eine (logische) 
Makrozeile mit '\' am Zeilenende über mehrere physikalische Zeilen 
verteilen.

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:
> Wie man sieht, wird der Initialisierungscode aus hallo_static in _GSINIT
> am Ende angehängt. Nach allen Initialisierungsabschnitten der C-Dateien
> (hier gibts nur den einen), kommt die GSFINAL-Area mit dem ret-Befehl.

Ich kann Dir grad genau sagen was dabei herauskommt wenn ich deine 
crt0.s verwende:

CD 00 00 oder anders call 0x0000 im Hex File, also Brennfile.

beim Aufruf call  gsinit. Immerhin was Neues, gabs noch nicht.

Init lokaler Vars zu Fuss:

                         123 ;interrupts.c:21: static int variable = 5;
   0000 FD 21r51r00   [14]  124   ld  iy,#_nmi_vint_variable_1_77
   0004 FD 36 00 05   [19]  125   ld  0 (iy),#0x05

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:

Mit einer Antwort warte ich wohl noch eine Weile. Man weiß ja nie, wie 
oft Du den Text noch änderst, oder wieviele Abschnitte, die alles wieder 
anders aussehen lassen, anhängst.

von Christian J. (Gast)


Lesenswert?

ES GEHT NICHT !

Ok?

Ich habe das schon hundertmal durchprobiert.... diese sch..... GSINIT 
liegt immer falsch !

Lassen wir es hier auch bitte gut sein. Es hat so funktioniert und ich 
habe auch keine Lust mehr da ewig dran zu sitzen, warum das mit den 
.areas so ist und nicht anders. Ich kann noch mal deine Sache gleich 
durchkompilieren aber dazu brauche ich zeit,.

von Leo C. (rapid)


Lesenswert?

Lieber Christian,
mit den zwei Schnipseln oben kann man ohne weiteren Kontext absolut 
nichts anfangen. Ganz ehrlich.

von Christian J. (Gast)


Lesenswert?

Hier die crt0.s und den Memory Dump musst du mir glauben, den ich im 
Brenner Tool sehe und wo der Call auf 0x0000 zeigt. vorher nach 0x2000.
1
;--------------------------------------------------------------------------
2
; crt0.s - Generic crt0.s for a Z80
3
;
4
; Minimum Z80 System mit Mostek 3801 Multi I/O Chip
5
; 
6
;--------------------------------------------------------------------------
7
8
    .module crt0            ; Modul Name für den Linker
9
 
10
    ; Memory Map Adressen der Zeropage (vom Benutzer definierbar)
11
    ; 0x00                  Reset Vector und Aufruf Hauptprogramm
12
    ; 0x38                  Mode 1 Int Vektor
13
    ; 0x40                  Mode 2 Vektor Tabelle für STI Mostek Multi I/O
14
    ; 0x66                  NMI Reset Vektor
15
    ; 0x80                  Copyright String
16
    ; 0x100                 User Programm
17
18
    ; Definitions
19
    stack            .equ   0xffff   
20
    adr_vec_table    .equ   0x40     
21
    adr_nmi          .equ   0x66      
22
    adr_copyright    .equ   0x80
23
    adr_userprog     .equ   0x100
24
25
    ; Globale Funktionen und Variablen für das C-Programm
26
27
    .globl  _main
28
    .globl  _nmi_vint       ; Funktion des NMI Handlers
29
30
    ; Interruptroutinen für den Mostek MK3801 Multi I/O Baustein
31
    ; Manual STI Baustein MK3801 Figure 7
32
    .globl  _int_sti_gpi_0  ; General Purpose Interrupt 0
33
    .globl  _int_sti_gpi_1  ; General Purpose Interrupt 1
34
    .globl  _int_sti_gpi_2  ; General Purpose Interrupt 2
35
    .globl  _int_sti_gpi_3  ; General Purpose Interrupt 3
36
    .globl  _int_sti_timer_d
37
    .globl  _int_sti_timer_c
38
    .globl  _int_sti_gpi_4  ; General Purpose Interrupt 4
39
    .globl  _int_sti_gpi_5  ; General Purpose Interrupt 5
40
    .globl  _int_sti_timer_b
41
    .globl  _int_sti_transmit_error
42
    .globl  _int_sti_transmit_buffer_empty
43
    .globl  _int_sti_receive_error
44
    .globl  _int_sti_receive_buffer_full
45
    .globl  _int_sti_timer_a
46
    .globl  _int_sti_gpi_6  ; General Purpose Interrupt 6
47
    .globl  _int_sti_gpi_7  ; General Purpose Interrupt 7
48
    ; Mode 1, alles auf eine Routine umleiten
49
    .globl  _int_sti_all
50
    
51
    .globl l__INITIALIZER
52
    .globl s__INITIALIZER
53
    .globl s__INITIALIZED
54
55
    ; -------------------------------------------------------------
56
57
    .area   _HEADER (ABS)   
58
    ; Reset vector bei Kaltstart und Sprung ins User Programm
59
    .org    0
60
     jp init
61
     
62
     ;; Tabelle der RST Vektoren für Software Interrupts
63
     .org 0x08
64
     ret
65
     .org 0x10
66
     ret
67
     .org 0x18
68
     ret
69
     .org 0x20
70
     ret
71
     .org 0x28
72
     ret
73
     .org 0x30
74
     ret
75
     ;.org 0x38
76
     ;reti
77
      
78
    
79
    ;///////////////////////////////////////////////////////////
80
    ;// Mode 1 Interrupt
81
    .org 0x38
82
    jp _int_sti_all
83
84
85
    ;///////////////////////////////////////////////////////////
86
    ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul
87
    ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle
88
    .org 0x40
89
    .dw (_int_sti_gpi_0)
90
    .dw (_int_sti_gpi_1)
91
    .dw (_int_sti_gpi_2)
92
    .dw (_int_sti_gpi_3)
93
    .dw (_int_sti_timer_d)
94
    .dw (_int_sti_timer_c)
95
    .dw (_int_sti_gpi_4)
96
    .dw (_int_sti_gpi_5)
97
    .dw (_int_sti_timer_b)
98
    .dw (_int_sti_transmit_error)
99
    .dw (_int_sti_transmit_buffer_empty)
100
    .dw (_int_sti_receive_error)
101
    .dw (_int_sti_receive_buffer_full)
102
    .dw (_int_sti_timer_a)
103
    .dw (_int_sti_gpi_6)
104
    .dw (_int_sti_gpi_7)
105
    
106
    ;///////////////////////////////////////////////////////////
107
    ; NMI Interrupt 0x66, muss mit retn abgeschlossen werden
108
    .org  0x66
109
    jp _nmi_vint        ; Aufruf Handler im C Modul main.c
110
    
111
    ;///////////////////////////////////////////////////////////
112
    ; Anordung der Segmente fuer den Linker, ab hier nur relative
113
    ; Adressen
114
115
      .area  _CODE
116
      .area  _INITIALIZER
117
      .area  _HOME
118
      .area  _GSINIT
119
      .area  _GSFINAL
120
      .area  _DATA
121
      .area  _INITIALIZED
122
      .area  _BSEG
123
      .area  _BSS
124
      .area  _HEAP
125
    
126
    ;///////////////////////////////////////////////////////////
127
    ;; ------- Start des Hauptprogramms nach der Zeropage  -----------
128
    
129
    .area _CODE
130
    init:
131
    
132
    ld  sp,#stack   ;; Stack an Spitze des RAM legen
133
    
134
    call gsinit
135
    
136
    ; Teste ob Userprogramm im RAM vorhanden
137
    ; ....
138
    
139
    ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt)
140
    xor     a             ; clear a and carry
141
    ld      bc,#0xdfff    ; ram size left
142
    ld      hl,#0x2000    ; starting from 2000
143
    ld      de,#0x2001
144
    ld      (hl),a        ; 0 -> (2000) 
145
    ldir                  ; (HL) -> (DE)
146
147
    ; ###### Hauptprogramm aufrufen #######
148
    call  _main       
149
endlos:
150
    halt
151
    jr endlos
152
    
153
   .area  _GSINIT
154
    
155
    ; Initialisiere globale Variablen im RAM
156
    ld  bc, #l__INITIALIZER
157
    ld  a, b
158
    or  a, c
159
    jr  Z, weiter
160
    ld  de, #s__INITIALIZED
161
    ld  hl, #s__INITIALIZER
162
    ldir
163
    
164
weiter:    
165
    
166
    ; // Hier muss ein ret rein  
167
    .area _GSFINAL
168
      ret

von Christian J. (Gast)


Lesenswert?

Bei Dir sieht das ja auch anders aus
da wird die Numerierung beo 0xc72 fortgesetzt, bei mir bei 0.



  0119 C9            [10]  165     ret
                            166
                            167     ; Initialisiere globale Variablen im 
RAM
                            168     .area   _GSINIT
   0C72                     169 gsinit::
   0C72 01 02 00      [10]  170     ld  bc, #l__INITIALIZER
   0C75 78            [ 4]  171     ld  a, b
   0C76 B1            [ 4]  172     or  a, c
   0C77 28 08         [12]  173     jr  Z, weiter
   0C79 11 02 20      [10]  174     ld  de, #s__INITIALIZED
   0C7C 21 70 0C      [10]  175     ld  hl, #s__INITIALIZER
   0C7F ED B0         [21]  176     ldir
   0C81                     177 weiter:


meines:

                           151
                            152     ; ###### Hauptprogramm aufrufen 
#######
   0013 CDr00r00      [17]  153     call  _main
   0016                     154 endlos:
   0016 76            [ 4]  155     halt
   0017 18 FD         [12]  156     jr endlos
                            157
                            158    .area  _GSINIT
                            159
                            160     ; Initialisiere globale Variablen
   0000 01r00r00      [10]  161     ld  bc, #l__INITIALIZER
   0003 78            [ 4]  162     ld  a, b
   0004 B1            [ 4]  163     or  a, c
   0005 28 08         [12]  164     jr  Z, weiter
   0007 11r00r00      [10]  165     ld  de, #s__INITIALIZED
   000A 21r00r00      [10]  166     ld  hl, #s__INITIALIZER
   000D ED B0         [21]  167     ldir
                            168
   000F                     169 weiter:

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Hier alles zusammen, ich arbeite ohne Makefile, nur mit compile.sh

von Christian J. (Gast)


Lesenswert?

Wie kriegt man deine Kompiliert?

>make
> Fuer das Ziel all ist nichts zu tun"

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Hier die crt0.s und den Memory Dump musst du mir glauben, den ich im
> Brenner Tool sehe und wo der Call auf 0x0000 zeigt. vorher nach 0x2000.

Das muß ich überhaupt nicht glauben. ;) Schließlich habe ich oben den 
Linkerschalter gepostet. Falls Du immer noch das Shellscript zum 
compilieren verwendest, dann schreib doch mal das -u dazu. Konkret:
1
sdcc -mz80 --verbose --no-std-crt0 -Wl-u --code-loc 0x0100 --data-loc 0x2000 crt0.rel main.rel
Und dann schau dir die *.rst-Dateien an.

von Christian J. (Gast)


Lesenswert?

Moment...

von Leo C. (rapid)


Lesenswert?

>make
> Fuer das Ziel all ist nichts zu tun"

In dem Archiv war ja auch alles schon fertig

$ make clean
$ make

von Christian J. (Gast)


Lesenswert?

Compiler option -W1-u ignored

ich krieg sie gleich ...

von Christian J. (Gast)


Lesenswert?

Bei Dir liegt alles richtig, bei mir falsch :-(

Kann also nur noch daran liegen dass ich ohne Makefile arbeite. ich 
versthehe von den Dingern nichts, habe sie noch nie benötigt. Kann ich 
das auch für 3 oder 4 Source dateien modifizieren? Bei mir binde ich die 
anderen dateien ja direkt ein, so dass nur noch main.c existiert für den 
Compiler.

-u geht nur bei sdld nicht bei sdcc

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Compiler option -W1-u ignored
                    ^
Das muß ein l sein. ell ell ell

Außerdem:
?ASlink-Warning-Undefined Global 'gsinit' referenced by module 'crt0'

Das label 'gsinit' fehlt in Deiner crt0. Da kommt dann auch der 'Call 
0x0000' her.

Das kommt davon, wenn man dem Assembler sagt, er soll alle undefinierten 
Symbole als Global annehmen. Das wiederum liegt aber nicht an Dir.

von Christian J. (Gast)


Lesenswert?

Zusammenfassung:

Ich brauche eine Weile um das alles auf Makefile umzuschrieben. Das 
scheint mir auf jeden Fall sinnvoller, denn auch sonst überall wird 
zuerst alles kompiliert und dann gelinkt. All in One kenne ich nur vom 
CCS Compiler für PIC, der kann auch nur ein File verarbeiten und man 
muss tricksen, damit man mehr haben kann.

Von Makefiles verstehe ich nichts, das hat bisher die jeweilige IDE 
alles übernommen.

Es geht also nur darum ob es durch Ergänzung der Zeile SRC im Makefile 
um die anderen .c Sourcen ausreicht das Projekt zu kompilieren?

von Christian J. (Gast)


Lesenswert?

Habe das korrigiert, es wird immer noch CD 00 00 erzeugt, da _GSINIT auf 
0x0000 definiert wurde.

Bevor ich das alles umgearbeitet habe mache ich hier erstmal Sendepause. 
So schnell kann ich das nicht.

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Kann ich das auch für 3 oder 4 Source dateien modifizieren?

Ja, einfach an die Zeile 'SRC = ' anfügen. Den Namen des Outputs (Hex- 
und bin-File kannst Du unter TARGET anpassen.

> Bei mir binde ich die
> anderen dateien ja direkt ein, so dass nur noch main.c existiert für den
> Compiler.

Das ist Murks.

von Christian J. (Gast)


Lesenswert?

das .rst File zeigt die gsinit übrigens an der richtigen Stelle.Da 
stimmt alles.

Jetzt wird aber kein .ihx File mehr erzeugt, warum weiss ich auch nicht. 
Vorher ging das problemlos....

-opt-code-size verhindert das aus welchen Gründen.

von Christian J. (Gast)


Lesenswert?

Bevor du mir beim Modifzieren wieder daszwischen funkst und ich den Text 
nicht mehr ändern kann:

--opt statt -opt..... und alles ist da.

Grad alles gebrannt und eingesteckt. Es läuft. Mit der .sh Methode. 
Alles liegt richtig. Wie gesagt arbeite ich das heute abend auf Makefile 
um, weil mir das vernünftiger zu sein scheint als der "Murks".

Dank Dir erstmal,war ne schwere Geburt aber das Kind ist da....

von Christian J. (Gast)


Lesenswert?

Hi,

kurze Rückmeldung. Nach fixer Umarbeitung des Source auf Makefile und 
einigen "extern" die zugeführt werden mussten lief die Kiste auf Anhieb.

Gruss,
Christian

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

So.....

mit dem Ram upload geht das Ganze doch schon deutlich entspannter vor 
sich als mit der EEPROM Stöpselei. Und bei einem reset bleibt auch alles 
im Ram erhalten und wird gestartet. NMI, Mode 2 Ints, alles klappt.

Etwas nervig ist derzeit noch die fixe Größe der .bin datei da unnützer 
Müll übertragen wird aber aktuell fällt mir noch nichts Gescheites ein, 
wie ich sehr einfach das Ende des Datenstromes erkennen kann in dem ich 
die Dateilänge vorher sende ohne dass ich die Ascii Zeichenkette mit 
variabler Länge wiederin Binärzahlen wandeln muss.Gibt zwar ein paar 
umständliche Lösungen aber die gefallen mir alle nicht.

Der Upload "Monitor" ist grad mal 150 Bytes.

Wens interessiert, noch absolut suboptimal weil kein Fehlerababfangen 
etc aber es läuft. "st" sind die Startzeichen, die nacheinander erkannt 
werden müssen, "--" bläst irgendwelchen Einschalt-Einstöpsel-müll vorher 
raus, danach kommen die Daten fixer Länge. echo -n muss sein, da sonst 
ein Zeilentrenner mit gesendet wird.
1
#!/bin/bash
2
dd if=z80rom.bin of=z80rom4.bin ibs=4096 conv=sync
3
echo "Datei zum Target uebertragen..."
4
stty raw ospeed 9600 -F /dev/ttyUSB0
5
echo -n "--st" > /dev/ttyUSB0
6
cat z80rom4.bin > /dev/ttyUSB0

Etwas tricky ist die Verwendung von Variablen im Monitor Programm, da 
die nicht durch den Ram Upload überschrieben werden dürfen. Man muss 
sich weit weg genug legen, knapp unter "die Decke" des RAM. Eine ASM 
Lösung nur mit Registern wäre hier sicherlich optimaler gewesen.

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> Etwas nervig ist derzeit noch die fixe Größe der .bin datei da unnützer
> Müll übertragen wird aber aktuell fällt mir noch nichts Gescheites ein,

So nervig können die paar Millisekunden doch nicht sein. Ansonsten: 
Lader für Intel-Hex einbauen. Das ist nicht so schwer, und Beispiele 
findes Du sicher massig im Netz.

Da war noch was in der Pipeline..

Christian J. schrieb:
> arbeite ich das heute abend auf Makefile
> um, weil mir das vernünftiger zu sein scheint als der "Murks".

"Murks" bezog sich nicht auf Script vs. Makefile. Du könntest ja auch im 
Script den Compiler für jede C-Datei einzeln aufrufen. Mit Murks meinte 
ich das hier:
1
// Einbindung von weiteren Modulen. 
2
#include "driver.c"
3
4
5
void main()
6
{
7
....
8
}
9
10
#include "interrupts.c"
11
12
// An das Ende des Codes die Interrupt Routinen dran hängen

Und dann stehen die includes noch nicht mal am Anfang der Datei, wo man 
sie noch leicht finden könnte, sondern In der Mitte und am Ende. Wie 
heißt nochmal die Steigerung von Murks? ;-)

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:
> Und dann stehen die includes noch nicht mal am Anfang der Datei, wo man
> sie noch leicht finden könnte, sondern In der Mitte und am Ende. Wie
> heißt nochmal die Steigerung von Murks? ;-)

Tja, da denkst du wieder nicht soweit wie ich...... das habe ich ganz 
absichtlich gemacht, damit ich im Editor den .lst Code schnell 
wiederfinde und nicht mittendrin suchen muss, weil sich bei jedem 
Kompliervorgang die Fenster neu laden und der Cursor nach oben springt. 
Ich wollte die Ints hinten im Code liegen haben :-) Ich musste wegen dem 
Brenner unter Windows arbeiten und hatte folgendes Chaos auf dem 
Bildschirm:

Brenneranwendung
Notepad ++
putty Kompilier-Window zum Cubietruck wo die Z80 Sache abläuft
noch ein putty zum Cubietruck für die USB Schnittstelle
Terminalfenster für die Ausgabe

ganz schön eng ;:-)

// An das Ende des Codes die Interrupt Routinen dran hängen

Stand auch da!

>>Lader für Intel-Hex einbauen. Das ist nicht so schwer, und Beispiele
>>findes Du sicher massig im Netz.

Jede Menge aber die blasen die Code Size erst richtig auf durch scanf 
und jede Menge String Funktionen, schlucken ordentlich Memory im Ram und 
genau das habe ich nicht.

Wobei ....15 Minuten mal eingelesen und reingeschaut in das Format... 
das schreibe ich auch selbst in 1/2 Tag. Nur Record Typ 00 wird 
verwendet.

http://en.wikipedia.org/wiki/Intel_HEX

von S. R. (svenska)


Lesenswert?

Wenigstens Record Type 01 solltest du unterstützen, sonst ist dein Ziel 
- nämlich das Dateiende zu erkennen - relativ schwierig.

Geht übrigens auch ohne scanf und Stringfunktionen. Dann dürftest du den 
Lader in ein paar Bytes bekommen.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Ja, ich habe mir das alles nochmal angeschaut.

Problem ist, dass ich kein RTS/CTS habe, ich muss entweder on the fly 
decodieren oder eine ganze Zeile parsen und da ist nicht viel Zeit 
zwischen den Bytes (0,83ms = 3200 Maschinenzyklen, eher weniger), wenn 
ich Lib Funktionen benutze. Allerdings wird aus einer "5" auch durch 
Subtraktion von 0x48 auch eine \5,  und BCD nach Binaer ist schnell 
gemacht. Codeprüfung evtl drauf verzichten.

Den ganzen Satz auf einmal geht nicht, weil der das Ram füllt was ich ja 
brauche. Werde das Ganze heute mal in einer Statemachine codieren, 
wahrscheinlich in Asm.

Leo ? Bist du da?

Weisst Du ob der Compiler feststehende Ausdrücke hat, um zb die Adresse 
der Segmente (start und Ende) im Programmcode zu verarbeiten? Da würde 
einiges vereinfachen wie zb Prüfsummen über den RAM Bereich usw.

Das hier scheint ja sowas zu sein:

    .globl l__INITIALIZER
    .globl s__INITIALIZER
    .globl s__INITIALIZED

Sind die auch aus dem C Code erreichbar? Und gibt es davon noch mehr?

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Problem ist, dass ich kein RTS/CTS habe,

XON/XOFF Software Handshake verwenden.

von Leo C. (rapid)


Lesenswert?

A. K. schrieb:
> XON/XOFF Software Handshake verwenden.

Das hat er ja auch nicht. Er denkt ja jetzt schon über den Lader, den er 
erst partout nicht haben und dann in einem halben Tag fertig haben 
wollte, so laut nach, bis irgend jemand so genervt ist, daß er ihm eine 
fertige Lösung präsentiert...
Dabei könnte er ja durchaus mal eine Weile bei dem Binärlader bleiben, 
bis er ein besseres Gefühl für Codegrößen und 
Ausführungsgeschwindigkeiten bekommt. Ich bin nämlich der Meinung, daß 
es auch in C ohne Handschake gehen müßte. Frage mich allerdings, wie er 
auf 0,83ms/Zeichen kommt.

von Christian J. (Gast)


Lesenswert?

Leo C. schrieb:
> Er denkt ja jetzt schon über den Lader, den er
> erst partout nicht haben und dann in einem halben Tag fertig haben
> wollte, so laut nach, bis irgend jemand so genervt ist, daß er ihm eine
> fertige Lösung präsentiert...

Nur mal kurz so ganz abseits der Technik: Das Internet besteht aus 
Leuten, die bereit sind das was sie machen anderen zu präsentieren. Ich 
kriege das alles (irgendwann) auch so hin, ohne hier darüber auch nur 
ein Wort zu verlieren. Ingenieure und Techniker gelten nicht gerade als 
"sozial kompetent" wie mir viele Jahre im Job zeigten wo ich genügend 
Spinner kennenlernte, die man bloss nicht aus dem Labor lassen sollte.

Kein Thema, erledigt. Ein Mod kann den Thread gern zu machen. Ab hier 
gehts auch so weiter....

Die 0.83ms sind die reinen Maschinenzyklen, die vergehen, bis 9 x 1/9600 
s Zeit vergangen ist für ein 8N1 protokoll. Grob über den Daumen 
gepeilt.

von Leo C. (rapid)


Lesenswert?

Christian J. schrieb:
> 8N1 protokoll

Start- und Stop-Bit?

: Bearbeitet durch User
von Holm T. (Gast)


Lesenswert?

Wundere Dich doch bitte nicht Christian wenn hier Einer nach dem Anderen 
mitbekommt das Du Deine Probleme gerne gelöst bekommen hättest. :-)


Ich habe vor ein paar Dave Dunfields Mon85 auf ein olles tschechisches 
Board mit 8080 Prozessor und 2 Mhz portiert. Ich weiß nicht ob u das 
weißt, ein 8080 ist der Vorgänger des Z80 und zeichnet sich dadurch aus, 
das ihm der komplette Schattenregistersatz, die Indexregister, der IM2 
Interruptmode und etliche Z80 befehle fehlen (keine relativen Sprünge 
etc), der weiteren möchte der noch einen 2 Phasen Takt und 3 
Betriebsspannungen, trotzdem hat das Ding nur eine geringfügig geringere 
Rechenleistung als ein Z80. CP/M2 läuft auch darauf.

Der Monitor unterstützt jedenfalls bei dieser Gurke problemlos das laden 
von Intel-Hex Files, im meinem Falle über eine 8251 Uart. Da gibts kein 
Zeitproblem.

Den Monitor gibts hier:
https://github.com/phillipjohnston/8085-HI6130-Port/tree/master/Compiler/MON85

Evtl. möchtest Du da ja mal rein schauen, aber sei gewarnt, das 
Assembler File benutzt 8080 Mnemonics die nicht kompatibel zu Z80 
Mnemonics sind, der Maschinencode ist aber für beide Prozessoren 
identisch.

Es gibt aber auch jede Menge fertige Z80 Debug-Monitore die Leute schon 
ins Internet geladen haben, die haben nämlich kein Problem damit :-) und 
schwadronieren nicht nur drüber ..

Du wurdest gewarnt: Nimm eine SIO ..nein Du wusstest das besser.
Nimm IM2 .. nein..Du wusstest das besser.
Die wird nahegelegt Dich nach der Source eines IHEX Loaders umzusehen.. 
nein, Du kannst das selber..

Dann mach mal..

Gruß,

Holm

von Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite


Lesenswert?

Naja Holm
Man muß ihm schon zugestehen, dass er mit seinem Sturschädel schon 
weiter gekommen ist als manch andere Pussi hier im Forum und das ohne 
wirklich zu Ende durchdachtes Konzept.
Namaste

: Bearbeitet durch User
von Leo C. (rapid)


Lesenswert?

Leo C. schrieb:
> Wenn man dieses Beispiel ohne Framepointer compiliert, wird beim Laden
> des 2. Parameters das Zwischenergebnis in hl teilweise zerstört. (sdcc
> 3.4.0) :(

Der Bug wurde inzwischen bestätigt.
Er tritt leider schon bei so etwas trivialem auf:
1
int test(int pa, int pb)
2
{
3
  return pa*2 + pb;
4
}

Workaround: --fno-omit-framepointer

von (prx) A. K. (prx)


Lesenswert?

Leo C. schrieb:
> Das hat er ja auch nicht.

Brauchte er ja auch nicht.

> Er denkt ja jetzt schon über den Lader,
> den er erst partout nicht haben

Was er jetzt hat ist das, was ich ihm geraten hatte. Einen 
einfachstmöglichen Loader, um die Brennerei los zu sein. Dem Hex-Loader 
kann er sich jetzt im RAM widmen, um den erst ins EPROM zu bannen, wenn 
fertig.

> wollte, so laut nach, bis irgend jemand so genervt ist, daß er ihm eine
> fertige Lösung präsentiert...

Dabei hatte ich das schon beinahe, aber für SIO und nicht als C 
Programm. Aber psssst, nicht weitersagen. ;-)

> Ich bin nämlich der Meinung, daß
> es auch in C ohne Handschake gehen müßte.

Vermute ich auch. Aber schaden tuts auch nicht und er will ja was zu tun 
haben.

> Frage mich allerdings, wie er
> auf 0,83ms/Zeichen kommt.

9600bd, 8 Bits pro Byte. Aber für BISYNC hätte er dann doch den Z80 SIO 
nehmen müssen. ;-)

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Tse....tse....

sowas habe ich schon 1987 mit dem 8085 mal gemacht, aber mit anderen 
Werkzeugen und dem Kenntnisstand von damals auch ich "drin" war. Das ist 
Jahre her. Upload vom C64 in das Ram des 8085 Systems.

Es gibt noch einige Dinge nicht so erklärbar sind wie binäre 
Chaoszeichen nach dem Reset bei der Ausgabe über die Uart. Sporadisch, 
nicht ständig und immer in der ersten Zeile des Menu String Satzes. So 
als müsste die Uart sich erst "warmlaufen".

Der Hex Uploder ist erstmal Konzept, verbal aufgeschrieben. Die Zeit 
reicht nicht um eine ganze Zeile zu bearbeiten bei 1 Byte Puffer Groesse 
des STI, wo es alle 0,9 ms mit einem neuen Bytes klingelt.  Eas sei 
denn.... und dann verlassen wir den einfachen Bereich, ich mache die 
Zeicheneingabe über den Interrupt, spiele einen Puffer voll mit zwei 
Zeiger drauf, der dann vom Hauptprogramm abgearbeitet wird. Damit 
entkopple ich auf jeden Fall die Auswertung vom Datenstrom, da die Ints 
ja prior sind und jedes zeichen reingeholt wird.

Endresultat soll ja mal sein, dass ein kleines Menü da steht. Einfache 
Befehle per Handeingabe aufzurufen sind und der Upload auch manuell aus 
Menüpunkt durchgeführt wird.

Ein Erstellen im RAM und später brennen ins ROM ist nicht einfach, es 
warern unzählige Änderungen am Source nötig für die Adressen damit es 
aus dem RAM raus läuft, dam ich keine "Schlüsselwörter" kenne, die als 
Platzhalter fungieren.

Da schüttel ich mir aber nicht aus dem Ärmel sonst muss da estmal ein 
Konzept machen, ein pflichteheft.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> des STI, wo es alle 0,9 ms mit einem neuen Bytes klingelt.

Glaub ich dir nicht. Nicht bei 9600bd. Für die vorhin genannten 0,83ms 
bräuchtest du 12000bd.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

Über den Daumen! Fangen wir jetzt nicht an um die Mikrosekunden zu 
feilschen.

9600 baud = 9600 bit/s = 0,0001s / Bit

1 Byte 8N1 = 8 Bit Nutzlast + 2 Steuerbits = 10 Bits

=> 0,001s/byte = 1000 Bytes/s

Maschinentakt 3.964.000 Takte /s = 0,25us/Takt

=> 3964 Takte zwischen den Bytes

reicht für on-the-fly Decodierung aus aber NICHT um eine ganze Zeile
komplett zu decodieren.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> => 0,001s/byte = 1000 Bytes/s

Von hinten durch die Brust ins Auge. ;-)
9600bd bei 10 Bits sind 960 Bytes/s.

> reicht für on-the-fly Decodierung aus

Eben. Ok, das ist zunächst nicht absolut narrensicher, dafür wäre eine 
Adressvalidierung nötig, denn die könnte einen Übertragungsfehler haben.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Von hinten durch die Brust ins Auge. ;-)
> 9600bd bei 10 Bits sind 960 Bytes/s.

Jaaaaaaaa....

Ok. Das ist auf jeden Fall machbar, wenn man etwas in Asm schreibt und 
vielleicht auf prüfsumme etc verzichtet.

Der Abend ist noch lang.....

> denn die könnte einen Übertragungsfehler haben.

Hobby! Auf demSchreibtisch. Nicht Industrie! Keine Leitungen, die den 
Schrank verlassen daher auch keine Anwendung der Feldbus-Norm, die einen 
Zeitstempel+Frame+CRC etc verlangt :-)

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> => 3964 Takte zwischen den Bytes

Also mindestens 500 Befehle. Da geht einiges.

von Christian J. (Gast)


Lesenswert?

A. K. schrieb:
> Christian J. schrieb:
>> => 3964 Takte zwischen den Bytes
>
> Also mindestens 500 Befehle. Da geht einiges.

Fetch = 3 T-Zyklen
Decode = 3-4 T-Zyklen
Execute = 2-5 T-Zyklen

Eher deutlich weniger als 500. Worst Case eher 100-200.

Oder eer kriegt einen Arduino davor mit 12 Mhz, der das fix macht..... 
naja, nicht so ganze Retro vielliecht.

von (prx) A. K. (prx)


Lesenswert?

Christian J. schrieb:
> Fetch = 3 T-Zyklen
> Decode = 3-4 T-Zyklen
> Execute = 2-5 T-Zyklen

Quark. Wo hast du das den aufgelesen?

Einfache Befehle, die nur aus dem M1 Zyklus bestehen, brauchen 4 Takte. 
Fetch steckt in der ersten Hälfte vom M1, Decode in der zweiten (dem 
Refresh). Ausgeführt wird danach, währen dem M1 vom Folgebefehl.

: Bearbeitet durch User
von Christian J. (Gast)


Lesenswert?

@A.K.

Unbestätiogten Gerüchten zufolge, soll es bereits streng geheime 
Mikrocomputer geben, die den ganzen Klumpatsch an Chips auf EINEM 
EINZIGEN Chip haben! Mit 256kb Flassch, 80kb RAM, SIO, PIO, CTC, JTAG 
Debug Interface ... alles drauf!

Kannst du dir das vorstellen?
.
.
.
.
.
:-)

von (prx) A. K. (prx)


Lesenswert?

Und was willst du mir damit sagen? Sorry, aber wie der Z80 tickt und 
timet weiss ich. Also das Original von Zilog aus den 70ern. Wer mal die 
Arbeitsweise eines Sinclar ZX80 analysiert hat, der kennt das, Sir Clive 
hatte da einige Tricks ausgenutzt.

Und wenn du damit ausdrücken willst, es hätte in damaligen 
Mikroprozessoren keine Überlappung von F/D/X Phasen gegeben (= 
Pipelining), dann darf ich dich korrigieren. Es hat. Im 6502 auch.

: Bearbeitet durch User
von Leo C. (rapid)


Angehängte Dateien:

Lesenswert?

A. K. schrieb:
> Und was willst du mir damit sagen?

Das das Thema unangenehm wird, und er es gerne wechseln möchte...

Im Anhang ist eine ein kompletter Intel-Hex-Lader in Assembler. Die 
Kommentare sind etwas spärlich, sollte aber reichen. Das Listing stammt 
ursprünglich aus einem Dissassembler. Hab den vor fast 30 Jahren auf ROM 
umgestellten ddtz auf dem Höhepunkt meines Retrofiebers ;) aus einem 
EPROM ausgelesen. Ein gedrucktes Listing hatte ich noch, so daß das ganz 
flott ging.

Der Lader addiert zu jedem Byte einen Offset (normalerweise 0), 
überprüft untere und obere Ladegrenze und checkt natürlich an jedem 
Record-Ende die gleichnamige Summe.

von Christian J. (Gast)


Lesenswert?

Sehr kompakt...... !

bevor ich gleich pause mache .... Experimente mit gets und atoi sind 
zwar erfolgreich aber allein atoi bläst den Code um fast 500 Bytes auf 
um aus "2000" ein 0x2000 zu machen. printf schießt ihn auf 5300 Bytes 
hoch und scanf dabei sprengt die 8KB Grenze fast.

Grundsätzlich aber ist mit minicom jetzt ein interaktiver Dialog 
möglich, mit Eingabe und Ausgabe.

printf("a=?")
scanf("%d",&a);
printf("b=?")
scanf("%d",&c);
printf("a+b=&d",a+b);

Läuft wie auf dem PC. Sehr nett...

von Georg G. (df2au)


Lesenswert?

Christian J. schrieb:
> 8N1

Das funktioniert natürlich, zeigt aber sofort den Theoretiker. 8N2 ist 
wesentlich robuster und nur unwesentlich langsamer.

(und ein Übertragungs "Protokoll" sind beide nicht)

von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> Tse....tse....
>
> sowas habe ich schon 1987 mit dem 8085 mal gemacht, aber mit anderen
> Werkzeugen und dem Kenntnisstand von damals auch ich "drin" war. Das ist
> Jahre her. Upload vom C64 in das Ram des 8085 Systems.

Ich nicht, ich hatte damals schon Z80.
Ich habe aber im Wesentlichen die olle Karte repariert:

http://www.tiffe.de/Robotron/TESLA/SM2138/P4070208s.JPG

und wie man sieht ist due auch nicht so bestückt wie ursprünglich mal 
vorgesehen, die ziemlich vergriesgnaddelten Schaltpläne die ich da 
bekommen habe waren nur teilweise hilfreich.

Das Ding stammt aus einem alten TESLA Terminal (CM7201 IMHO) das mal an 
einem tschechischen Nachbau einer PDP11 tätig war.

Ich habe das eigntlich nur repariert um einem Freund aus dem 
Robotron-Forum die Reparatur des Terminals leichter zu machen,
allerdings hat dieser in einem Anfalls von Aufräumwahn das Terminal 
entsorgt als ich fertig war. Die Karten von dem Ding hat er aber 
aufgehoben.

Ich habe nun drüber nachgedacht Sohnemann das Ding zum Spielen auf den 
Tisch zu legen, mit einer 7Seg Anzeige und einer Hexa Tastatur dran,
Allerdings ist Jemand aus dem Robotron-Frorum gerade dabei den LC80 neu 
aufzulegen, sowas wie die DDR Variante des "Mikroprofessors", ist wegen 
existierendem Handbuch sicher besser geeignet und mit Z80.

>
> Es gibt noch einige Dinge nicht so erklärbar sind wie binäre
> Chaoszeichen nach dem Reset bei der Ausgabe über die Uart. Sporadisch,
> nicht ständig und immer in der ersten Zeile des Menu String Satzes. So
> als müsste die Uart sich erst "warmlaufen".

Frequenzzähler an den Taktgenerator hängen...

>
> Der Hex Uploder ist erstmal Konzept, verbal aufgeschrieben. Die Zeit
> reicht nicht um eine ganze Zeile zu bearbeiten bei 1 Byte Puffer Groesse
> des STI, wo es alle 0,9 ms mit einem neuen Bytes klingelt.  Eas sei
> denn.... und dann verlassen wir den einfachen Bereich, ich mache die
> Zeicheneingabe über den Interrupt, spiele einen Puffer voll mit zwei
> Zeiger drauf, der dann vom Hauptprogramm abgearbeitet wird. Damit
> entkopple ich auf jeden Fall die Auswertung vom Datenstrom, da die Ints
> ja prior sind und jedes zeichen reingeholt wird.
>
> Endresultat soll ja mal sein, dass ein kleines Menü da steht. Einfache
> Befehle per Handeingabe aufzurufen sind und der Upload auch manuell aus
> Menüpunkt durchgeführt wird.
>
> Ein Erstellen im RAM und später brennen ins ROM ist nicht einfach, es
> warern unzählige Änderungen am Source nötig für die Adressen damit es
> aus dem RAM raus läuft, dam ich keine "Schlüsselwörter" kenne, die als
> Platzhalter fungieren.
>
> Da schüttel ich mir aber nicht aus dem Ärmel sonst muss da erst mal ein
> Konzept machen, ein pflichteheft.

Christian, das Laden von Intel Hex Dateien funktioniert aus diesen 8 Bit 
Prozessoren seit über 20 Jahren ohne Zeitprobleme und damals liefen die 
Teile eher nicht mit 4Mhz.

Gruß,

Holm

von Christian J. (Gast)


Angehängte Dateien:

Lesenswert?

Holm Tiffe schrieb:
> Christian, das Laden von Intel Hex Dateien funktioniert aus diesen 8 Bit
> Prozessoren seit über 20 Jahren ohne Zeitprobleme und damals liefen die
> Teile eher nicht mit 4Mhz.

Holm,

nette Spielsachen, die du das hast..... da habe ich früher mit nem 
Luftgewehr drauf geschossen und geguckt wie das splittert :-) Sind 
sicher auf der Rückseite noch ein paar Gleichrichterröhren und Relais 
für die CPU? Wo ist denn der Anschluss für den Dampfdruck:-)

Nee..... mache das schon mit etwas mehr Komfort, auch wenn es bisher nur 
ein 1-Wort Parser ist. Bald wird es schon mehr ... so wie einst Linus 
Trovalds nur einen Terminal schreiben wollte und dann entdeckte, dass er 
ein Betriebssystem geschrieben hat ... da fühlt man sich wie Kolumbus 
vor der Entdeckung Amerikas :-)

Ich brauche kein Intel Hex mehr.... da wo ich hinfliege gibt es keine 
Strassen :-)

Das Doofe ist nur, dass auch Backspace, Pfeile etc übertragen werden und 
bei gets() lässt sich da nix filtern, das sichere fgets gibt es nicht 
und es werden echos erzeugt. minicom hat als echtes Terminal keinen <CR> 
übertragungsmode.

von Christian J. (Gast)


Lesenswert?

Etwas nervig ist nur das "Krücken-Script", da ich noch versuche mit der 
Bash warm zu werden und sogar das "Galileo Shell programming" in der 
Nähe des Kopfkissens liegen habe. Allein schon der Umstand mit den 
Leerzeichen, die mal fehlen und mal zuviel sind.

sleep kann nur 1s verzögern, ohne Verzögerung ist der PC zu schnell und 
es werden Zeichen verschluckt im riesigen 1-Byte Buffer der SIO.

Vorteil ist nur: Es klappt, zusammen mti Geany, da drin angepassten 
Kompilieroptionen ist es ein sehr kurzer Weg von der Änderung zum 
Testen. 2 Klicks um genau zu sein.
1
#!/bin/bash
2
echo "---------------------------------"
3
echo "Datentrasnfer zum Z80"
4
echo "---------------------------------"
5
6
echo "Stelle tty/USB0 auf 9600 baud ein....."
7
stty 9600 -crtscts -ixoff -F /dev/ttyUSB0
8
9
echo "Sende "load" Startsequenz...."
10
echo "load" > /dev/ttyUSB0
11
sleep 1
12
stat -c %s z80rom.bin > /dev/ttyUSB0
13
sleep 1
14
15
echo "Uebertrage Daten...."
16
cat z80rom.bin > /dev/ttyUSB0
17
sleep 1
18
echo "Sende "start" Signal um Upload zu starten..."
19
sleep 1
20
echo "start" > /dev/ttyUSB0
21
echo "Fertig!"

von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> Holm Tiffe schrieb:
>> Christian, das Laden von Intel Hex Dateien funktioniert aus diesen 8 Bit
>> Prozessoren seit über 20 Jahren ohne Zeitprobleme und damals liefen die
>> Teile eher nicht mit 4Mhz.
>
> Holm,
>
> nette Spielsachen, die du das hast..... da habe ich früher mit nem
> Luftgewehr drauf geschossen und geguckt wie das splittert :-) Sind
> sicher auf der Rückseite noch ein paar Gleichrichterröhren und Relais
> für die CPU? Wo ist denn der Anschluss für den Dampfdruck:-)
>
> Nee..... mache das schon mit etwas mehr Komfort, auch wenn es bisher nur
> ein 1-Wort Parser ist.

Du denkst scheinbar wirklich das Du da eine höhere Qualität erreicht 
hast?

Einbildung ist auch eine Bildung, mancher Leute Einzigste..

:-)

Komm mal wieder runter, in den ROMs der Platine steckt ein kompletter 
Debugger mit Assembler und Disassembler sowie u.A. auch ein IHEX Loader.
Da darfst Du noch eine Weile dran herumschrauben. Auch für den 8080 
Gibts C-compiler, BDS-C z.B. unter emuliertem CP/M.
Den Menüchen da sieht zwar schön grün aus, ist aber nicht im Geringsten 
irgendwie beeindruckend.

> Bald wird es schon mehr ... so wie einst Linus
> Trovalds nur einen Terminal schreiben wollte und dann entdeckte, dass er
> ein Betriebssystem geschrieben hat ... da fühlt man sich wie Kolumbus
> vor der Entdeckung Amerikas :-)

Joh..machmal.

>
> Ich brauche kein Intel Hex mehr.... da wo ich hinfliege gibt es keine
> Strassen :-)
>

Ist recht.

> Das Doofe ist nur, dass auch Backspace, Pfeile etc übertragen werden und
> bei gets() lässt sich da nix filtern, das sichere fgets gibt es nicht
> und es werden echos erzeugt. minicom hat als echtes Terminal keinen <CR>
> übertragungsmode.

Jaa, das ist einer der Gründe warum es Intel Hex gibt, brauchst Du aber 
nicht...ich weiß...

Gruß,

Holm

von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> Etwas nervig ist nur das "Krücken-Script", da ich noch versuche mit der
> Bash warm zu werden und sogar das "Galileo Shell programming" in der
> Nähe des Kopfkissens liegen habe. Allein schon der Umstand mit den
> Leerzeichen, die mal fehlen und mal zuviel sind.
>
> sleep kann nur 1s verzögern, ohne Verzögerung ist der PC zu schnell und
> es werden Zeichen verschluckt im riesigen 1-Byte Buffer der SIO.
>
> Vorteil ist nur: Es klappt, zusammen mti Geany, da drin angepassten
> Kompilieroptionen ist es ein sehr kurzer Weg von der Änderung zum
> Testen. 2 Klicks um genau zu sein.
>
>
1
> #!/bin/bash
2
> echo "---------------------------------"
3
> echo "Datentrasnfer zum Z80"
4
> echo "---------------------------------"
5
> 
6
> echo "Stelle tty/USB0 auf 9600 baud ein....."
7
> stty 9600 -crtscts -ixoff -F /dev/ttyUSB0
8
> 
9
> echo "Sende "load" Startsequenz...."
10
> echo "load" > /dev/ttyUSB0
11
> sleep 1
12
> stat -c %s z80rom.bin > /dev/ttyUSB0
13
> sleep 1
14
> 
15
> echo "Uebertrage Daten...."
16
> cat z80rom.bin > /dev/ttyUSB0
17
> sleep 1
18
> echo "Sende "start" Signal um Upload zu starten..."
19
> sleep 1
20
> echo "start" > /dev/ttyUSB0
21
> echo "Fertig!"
22
>

Oh Shit. Du überträgst wirklich Binärdaten über eine "nicht rohe" 
Schnittstelle. Laß Dir von Anderen erlären warum das keine gute Idee 
ist.
Auf Sowas schieße ich normalerweise heute noch mit dem Luftgewehr.

Dein Shellscript ist Scheiße. Es gibt Make und die dazugehörigen 
Makefiles die die Targets und deren Abhängigkeiten deklarieren. Diese 
Mechanismus wird sogar von den von Dir geliebten IDEs wie AVR-Studio 
benutzt, sollte einen Grund haben.

Gruß,

Holm

von S. R. (svenska)


Lesenswert?

Lass gut sein, Holm. Das ist Beratungsresistenz vom allerfeinsten.

von Christian J. (Gast)


Lesenswert?

Holm Tiffe schrieb:
> Dein Shellscript ist Scheiße. Es gibt Make und die dazugehörigen
> Makefiles die die Targets und deren Abhängigkeiten deklarieren.

Keine Ahnung von ....  man muss nicht alles wissen und können. Makefiles 
gehören bei mir dazu.

von Holm T. (Gast)


Lesenswert?

Christian J. schrieb:
> Holm Tiffe schrieb:
>> Dein Shellscript ist Scheiße. Es gibt Make und die dazugehörigen
>> Makefiles die die Targets und deren Abhängigkeiten deklarieren.
>
> Keine Ahnung von ....  man muss nicht alles wissen und können. Makefiles
> gehören bei mir dazu.

Jawoll!

Offensichtlich mußt DU nicht mal Wesentliches wissen, es reicht Dir 
Tatsachen einfach zu ignorieren. Ok, das ist auch eine Art 
Weltanschauung.

Gruß,

Holm

von Axel S. (a-za-z0-9)


Lesenswert?

Christian J. schrieb:

> ....  man muss nicht alles wissen und können. Makefiles
> gehören bei mir dazu.

Es gibt einen Unterschied zwischen "nicht wissen" und "nicht wissen 
wollen". Für letzteres gibt es eigene Begriffe wie "Lernresistenz".
Die meisten empfinden das als Schimpfwort. Du anscheinend nicht.


'nuff said, XL

von Christian J. (Gast)


Lesenswert?

Und tschüss !

von (prx) A. K. (prx)


Lesenswert?

Wär das nicht etwas für dich?

"Der Kernel-Hacker Alan Cox hat ein unixoides Betriebssystem für den 
8-Bit-Prozessor Zilog Z80 erstellt."

http://www.golem.de/news/fuzixos-alan-cox-zeigt-betriebssystem-fuer-8-bit-cpu-z80-1411-110302.html

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Cool

von Christian J. (Gast)


Lesenswert?

Läuft wohl nur auf Z180 oder als -lite Z80 mit Banked memory :-(

UZI180 makes extensive use of the Memory Management (MMU) of the Z180 
core
to provide as much process isolation as possible with the chip.  Since 
the
MMU granularity is 4k, this establishes the basic process structure. 
The
top 4k of logical address space (one MMU slice) is defined as Common1 
memory
space and contains critical routines that either must always be resident 
in

Minimal Requirements
--------------------

- Z80 processor
- 128K memory (the kernel itself wants between 32 and 40K R/O and about
  8-16K R/W depending upon the configuration.
- Some kind of memory banking giving a common area and multiple banks
- A storage device, preferable hard disk or SD card or similar
- A timer interrupt (but you can sort of run single user with just a 
serial
  / keyboard irq)

In the ideal world
  256K of RAM or more
  An RTC
  16K flexible memory banking

"....... Doch ganz ernst gemeint ist die Frage nicht, denn Fuzix bedient 
keinesfalls den Consumer- oder Desktop-Bereich, sondern richtet sich 
eher an Entwickler des in letzter Zeit vor allem im Enbedded-Bereich 
wiederentdeckten Zilog Z80 – ein 8-Bit-Mikroprozessor, der von der Firma 
Zilog Mitte der siebziger Jahre entwickelt wurde...."

von Holm T. (Gast)


Lesenswert?

Axel Schwenke schrieb:
> Cool

Nee, das kühlt mich nicht ab. Ich finde das hot!

Gruß,

Holm

von Christian J. (Gast)


Lesenswert?

Hmm....... das nächste Projekt? 512kB RAM.

http://www.zcontrol.narod.ru/diagrams/ZramBankSwitch.pdf

Grad durch die Sourcen durch ... ist noch sehr "rudimentär" aber alles 
für den SDCC, kompiliert so durch. Nur ein referenz Schaltplan wäre gut, 
Flopy usw scheint es auch zu geben.

Allerdings würde ich beim nächsten Mal eine Möglichkeit vorsehen 
Software Breakpoints zu setzen und einen Single Step Mode. Den vermisse 
ich doch etwas und missbrauche RST dafür derzeit, um den Monitor und das 
wachsende Intel-Hex Decoding zu debuggen.

von Christian J. (Gast)


Lesenswert?

Bei folgendes Thema habe ich leider nicht genug Kenntnissem, bzw hatte 
ich damit noch nie zu tun:

Ich benutze derzeit miniciom als Terminal. minicom schickt jeden 
Tastendruck an den Z80 und je nach Einstellung echot dieser es oder 
minicom macht es.

Ich möchte den Monitor doch schon noch etwas ausbauen und habe mir auch 
den Tiny Basic Interpreter besorgt für den AVR, der sich sicherlich 
anpassen lassen wird.

mincom soll bzw geht das überhaupt, dass der Z80 Steuerzeichen schickt, 
wie Cursor Move, Backspace usw und minicom tut genau das? zb einen 
blinkenden Cursor darstellen durch ein/aus eines _ usw? Die Eingabe soll 
genau der eines PC gleichen und mit EOL wird sie übernommen, an einen 
Parser gereicht und der decodiert dann den Befehl für den Z80 und die 
Parameterliste. Auf die Weise müsste sich eine erweiterbare Struktur 
bauen lassen die einfache Dinge erledigt und vielleicht später auch mal 
ein ganzes Basic Programm eingeben lässt bzw es auch abspeichert, da ich 
als "Floppy" ein 64K E2PROM im Auge habe, angesteuert durch einen AVR.

Ginge das mit minicom? Oder mit was anderem?

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
Noch kein Account? Hier anmelden.