mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg G. schrieb:
> Winfried J. schrieb:
>> der z80 macht keinen Kaltstart solange das Warmflag im Ram gesetzt ist!
>
> Wo hast du diese Weisheit her? Beim Z80 gibt es nur einen Reset Vektor,
> nämlich 0x0000. Der Rest ist Sache des Anwenders.

Christian J. schrieb:
> Warmstart-Flag? Bahnhof-Flag? Systemvariablen?

Boah, Leute. Mitdenken

Ein Monitorprogramm, das nach jedem Hardware-Reset einen Kaltstart [1] 
macht, ist keinen Pfifferling wert. Es braucht eine wenigstens halbwegs 
zuverlässige Heuristik, um zu entscheiden ob ein Kaltstart oder 
Warmstart erforderlich ist.

> Vectortabelle.... liegt im ROM, nur RETI drin.

Blöde Idee <tm>. Dann brauchst du auch keine Vektortabelle. Die Tabelle 
muß natürlich im RAM liegen. Mit Einträgen, die ins ROM zeigen.


XL

[1] ein Kaltstart beinhaltet i.d.R. sowas wie komplette Löschung des 
RAMs. Oft auch einen kurzen Selbsttest oder einen Scan, wo denn überall 
RAM liegt (damit man z.B. den Stack ans Ende setzen kann). Natürlich 
müssen nach einem Kaltstart alle im RAM liegenden Variablen und Tabellen 
(beim Z80 insbesondere die Vektortabelle) initialisiert werden.

[2] bei einem Warmstart versucht man, so wenig wie möglich RAM 
anzufassen, damit z.B. eine post mortem Analyse möglich bleibt. Einen 
Teil der Systemvariablen wird man aber trotzdem initialisieren wollen.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nabend,

er läuft... immmer, ohne Mucken, bei jedem Resetm, jedem Power Up .... 
hüstl.

Ohne ins Detail zu gehen..... man hole sich neben der Hardware nicht 
eine zweite Fehlerquelle ins Haus.... den SDCC Compiler. Denn der hat es 
in sich und erzeugt fehlerhaften Code bzw wenn man nicht Dinge tut, die 
andere schon herausgefunden haben, die aber nicht im Manual stehen und 
auch nicht behoben worden sind. Spüielreien wie mit meheren Source Files 
arbeiten, Prototypen definieren, extern Variablen usw. sollte man 
erstmal lassen, da wird "noch dran gearbeitet", da der Linker damit 
nicht klar kommt.

So muss die für den Z80 aussehen (Rohbau) und alles andere Zeugs da 
raus. Der Z80 braucht nicht mehr, Stackpointer setzen und loslaufen.
.module crt0
.globl _main
.area _HEADER (ABS)
;; Reset vector
.org 0x0000
jp init
init:
  ld  sp,#0xffff      ;; Oder Testen, wo RAM zu ende
    call  _main    ;; Hauptprogramm aufrufen
lo:  halt                    ;; oder jp lo für Endlosschleife

;; Initialise global variables
call gsinit
call _main
ret

;; Ordering of segments for the linker.
.area _HOME
.area _CODE
.area _GSINIT
.area _GSFINAL
.area _GSINIT
gsinit::
.area _GSFINAL
ret
.area _DATA
.area _BSEG
.area _BSS
.area _HEAP

Konkret muss die ctr0.s modifiziert werden und genau deshalb spielte der auch verrückt. 


8255 tut es auch, LEDs blinken, 7 Segment kommt noch.

*****************************************************

DANKE AN ALLE, DIE MIR BIS HIERHIN GEHOLFEN HABEN !

Ohne euch hätte ich das nie geschafft !

******************************************************

Autor: Michael_ (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Ein Monitorprogramm, das nach jedem Hardware-Reset einen Kaltstart [1]
> macht, ist keinen Pfifferling wert. Es braucht eine wenigstens halbwegs
> zuverlässige Heuristik, um zu entscheiden ob ein Kaltstart oder
> Warmstart erforderlich ist.

Vom Z-80 scheinst du keine Ahnung zu haben. Hardware-Reset ist 
Hardware-Reset!
Das ist beim PC als auch beim AVR so.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael_ schrieb:
> Das ist beim PC als auch beim AVR so.

Eben dieser PC ist ein schönes Beispiel, dass auch ein ziemlich brutal 
wirkender Prozessor-Reset nicht ganz das sein muss, was Du dir darunter 
vorstellst. Da Intel keinen Weg aus dem protected mode in den real mode 
vorgesehen hatte, mussten Systeme, die diesen Weg dennoch benötigten, 
anfangs im vollen Galopp während des Normalbetriebs den Prozessor-Reset 
dafür verwenden:
http://en.wikipedia.org/wiki/Protected_mode#Entering_and_exiting_protected_mode

Der Trick besteht darin, im Monitor-Programm (oder eben dem BIOS) nicht 
gleich Grossputz zu machen. Sondern zu erkennen, dass im RAM sinnvoller 
Inhalt ist, der genutzt werden will.

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

Bewertung
0 lesenswert
nicht lesenswert
Michael_ schrieb:
> Axel Schwenke schrieb:
>> Ein Monitorprogramm, das nach jedem Hardware-Reset einen Kaltstart [1]
>> macht, ist keinen Pfifferling wert. Es braucht eine wenigstens halbwegs
>> zuverlässige Heuristik, um zu entscheiden ob ein Kaltstart oder
>> Warmstart erforderlich ist.
>
> Vom Z-80 scheinst du keine Ahnung zu haben. Hardware-Reset ist
> Hardware-Reset!

Und du scheinst nicht lesen zu können.

Natürlich startet der Z80 nach einem Reset immer bei 0000H. Aber was 
er dann macht, bestimmt das Monitorprogramm. Und wie bereits dargelegt, 
wäre es höchst kontraproduktiv, wenn es dann immer einen Kaltstart 
macht.


XL

Autor: Georg A. (georga)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
> Denn der hat es in sich und erzeugt fehlerhaften Code bzw wenn man
> nicht Dinge tut, die andere schon herausgefunden haben, die aber
> nicht im Manual stehen und auch nicht behoben worden sind.

Och und ich dachte schon, das hätte sich zu meinem sdcc-Ärger im 
8051-Mode von vor 14 Jahren mal irgendwie gebessert...

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg A. schrieb:
>> Denn der hat es in sich und erzeugt fehlerhaften Code bzw wenn man
>> nicht Dinge tut, die andere schon herausgefunden haben, die aber
>> nicht im Manual stehen und auch nicht behoben worden sind.
>
> Och und ich dachte schon, das hätte sich zu meinem sdcc-Ärger im
> 8051-Mode von vor 14 Jahren mal irgendwie gebessert...

Naja... so ganz frisch ist die Support Homepage auch nicht mehr... 
hüstl

17.05.09
Added a simple keyboard driver by Manoel Andrade
Added a tool source by Stephan Le Meunier for counting machine cycles 
(mcs51)

Ich schau dem Kleinen grad die ganze Zeit beim "Bit-Schaufeln" zu, wenn 
die LED anzeigen wo er grad ist beim RAM umschaufeln ....echt retro 
sowas :-) Ok, die Programmierung ist Einheitsbrei aber bald werde ich 
sicherlich noch voller Entzückung das Assembler-Gestammel lernen.... was 
schreibt sich eigentlich schneller?

foo |= (1<<nr);   // 2s zum tippen...

oder incl "überlegen" das hier. Gefühlt 3 Minuten....
  ld  a,4 (ix)
  inc  a
  push  af
  ld  e,#0x01
  pop  af
  jr  00110$
00109$:
  sla  e
00110$:
  dec  a
  jr  NZ,00109$
  ld  a,d
  or  a, e
  ld  d,a
  jr  00103$

Ein Blick auf die Stromanzeige des Netzteils lässt allerdings die Frage 
aufkommen, ob Batterie-Applikationen vielleicht nicht so ganz angebracht 
waren damals... die NMOS CPU, die seit 1985 nicht mehr benutzt wurde ist 
erstens sehr heiss und auch der Rest hat einen gesunden Durst, 180mA die 
ganze Platine.

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist weniger als 1 Watt Leistung und völlig Ok.

>  inc  a
>  push  af
>  ld  e,#0x01
>  pop  af
>  jr  00110$

Wozu push af und pop af?
Ein Z80 hat Befehle für Bitmanipulation.

Gruß,

Holm

: Bearbeitet durch User
Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> die NMOS CPU, die seit 1985 nicht mehr benutzt wurde ist
> erstens sehr heiss und auch der Rest hat einen gesunden Durst, 180mA die
> ganze Platine.

Ist doch völlig ok. NMOS heisst Dauerstrom, ob sie rennt oder pennt.

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> oder incl "überlegen" das hier. Gefühlt 3 Minuten....

Der Compiler hat dafür garantiert keine 3 Minuten gebraucht, und auch 
keine 2 Sekunden. Wer auf die Idee kommt, sowas zu programmieren, und 
kein Compiler ist, ist ja wohl mit dem Klammerbeutel gepudert.

Holm Tiffe schrieb:
> Wozu push af und pop af?
> Ein Z80 hat Befehle für Bitmanipulation.

Wahrscheinlich hat er die Optimierung nicht eingeschaltet.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
push  af
ld  e,#0x01
pop  af

Das verstehe ich ehrlich gesagt auch nicht..... Optimierungen sind ein, 
aber ich habe das Gefühl, dass er mit dynamischen Variablenb, also 
Overlays auch Probleme hat. Der sheint die immer static anzulegen.

Autor: Michael_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Natürlich startet der Z80 nach einem Reset immer bei 0000H. Aber was
> er dann macht, bestimmt das Monitorprogramm. Und wie bereits dargelegt,
> wäre es höchst kontraproduktiv, wenn es dann immer einen Kaltstart
> macht.

Bei klassischen Z-80 war das nicht üblich. Da wurde alles neu 
initialisiert.
Wenn man Flash hat, kann man leicht eine Variable ablegen, welche man 
beim Neustart abfragt.
Damals wäre das höchstens mit einem gepufferten C-MOS-RAM gegangen. Dies 
war aber nicht üblich.

Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hängt vom Anwendungsfall ab. Der KC85 hat beispielsweise den RAM beim 
Warmstart nicht neu initialisiert, damit langwierig von Kassette 
geladene Anwendungen erhalten blieben. Bei Editoren u.ä. konnte man 
selbst entscheiden, ob man den Datenbereich neu initialisiert haben 
wollte (BASIC, WORDPRO) oder nicht (REBASIC, REWORDPRO). Dazu braucht es 
keinen gepufferten CMOS SRAM, das ging auch ohne prima.

Was den SDCC angeht... der ist leider ziemlich beschränkt in seinem 
Weltbild. Aber sonst kenne ich nur den z88dk als halbwegs aktuellen 
C-Compiler für Z80.

Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael_ schrieb:
> Axel Schwenke schrieb:
>> Natürlich startet der Z80 nach einem Reset immer bei 0000H. Aber was
>> er dann macht, bestimmt das Monitorprogramm. Und wie bereits dargelegt,
>> wäre es höchst kontraproduktiv, wenn es dann immer einen Kaltstart
>> macht.
>
> Bei klassischen Z-80 war das nicht üblich. Da wurde alles neu
> initialisiert.

Mit Verlaub, aber das ist Unsinn. Für die hier diskutierte Geräteklasse 
der Eigenbau-Computer gibt es gar kein üblich. Da waren die Monitore / 
BIOSe handgeklöppelte Einzelanfertigungen und haben gemacht was ihr 
Herrchen für sinnvoll hielt, nicht was üblich war (nach wessen Maßgabe 
eigentlich?). Aber auch der Z9001 aka KC87 hat z.B. sein RAM nach einem 
Reset nicht gelöscht. U.a. damit von Kassette nachgeladene 
Betriebssystemerweiterungen erhalten blieben.

> Wenn man Flash hat, kann man leicht eine Variable ablegen, welche man
> beim Neustart abfragt.
> Damals wäre das höchstens mit einem gepufferten C-MOS-RAM gegangen. Dies
> war aber nicht üblich.

Jo. Und genau deswegen sprach Winfried von einem Flag im RAM. Weil RAM 
damals das einzige war, wo man sowas ablegen konnte. Und natürlich 
bringt das seine eigenen Probleme mit sich. Z.B. daß so ein Flag nach 
dem Kaltstart auch zufällig im RAM stehen kann. Weswegen man 
essentielle Initialisierungen (Stack, Interrupt-Vektoren) immer machen 
muß. Oder daß man bei einem Reset im laufenden Betrieb irgendwie den 
Refresh von evtl. vorhandenem DRAM sicherstellen muß.

Aber nur weil du sowas nie gesehen (wohl eher: immer übersehen) hast und 
dir nie Gedanken darüber machen mußtest, heißt ja nicht daß es das nicht 
gab oder gibt.


XL

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

Bewertung
0 lesenswert
nicht lesenswert
naja,

ich komm halt vom ATARI mit seiner 65C02. Die hatte auch nur RESET (auf 
0xFFFF) aber die Resetroutine  des Original-BIOS fragte als erstes das 
Warmflag im RAM ab, danach entschied sie über Kalt~ oder Warmstart. Im 
Kaltstartfall wurde dann mal gleich die Zeropage (0x000-0x400) 
initialisiert. Hier fanden sich alle nötigen Variablen und Vektoren des 
BIOS, da dieser RAM-Bereich mit minimaler Taktzyklenzahl zu lesen und zu 
schreiben war.
...
Ich habe dann das Bios mit meinem Modifikationen in RAM Bänke hinter dem 
BIOS Rom geladen und dann mit gesetztem Warmflag das ROM abgesaltet und 
einen Reset ausgelöst  schon lief mein Bios aus dem RAM und konnte 1MB 
in 16kB Blöcken einblenden das war schon recht ordentlich für einen 
8-Bitter.

ich meine damals auch aus der ZX-Spectrumecke solches gehört zu haben 
und muss mich schon sehr wundern hier so abgebürstet zu werden.
eigentlich wa mir nur daran gelegen auf mögliche fehlerquellen in 
Startroutinen hinzuweisen. Aber sollte der TO daran weiters kein 
Interesse haben....

Ich hab auch genug anderes zu tun.

@ Axel wir sind wohl zu alt für diese Retrowelt. Da ist ein 
Geradeausämpfänger das Grösste. Einen DoppelSuper baut hier keiner nach, 
geschweige ein vernünftiges BIOS.

PS meinen Monitor habe ich natürlich auch selbst erweitert und in 
Assembler daran rumgestrickt.
mit C Habe ich erst beim 386 angefangen.
Namaste

: Bearbeitet durch User
Autor: Michael_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Mit Verlaub, aber das ist Unsinn. Für die hier diskutierte Geräteklasse
> der Eigenbau-Computer gibt es gar kein üblich. Da waren die Monitore /
> BIOSe handgeklöppelte Einzelanfertigungen und haben gemacht was ihr
> Herrchen für sinnvoll hielt, nicht was üblich war (nach wessen Maßgabe
> eigentlich?). Aber auch der Z9001 aka KC87 hat z.B. sein RAM nach einem
> Reset nicht gelöscht. U.a. damit von Kassette nachgeladene
> Betriebssystemerweiterungen erhalten blieben.

Habs mir mal angeschaut. Reset ist eben nicht Reset.
Beim obigen ist es eher ein Soft-Wiederstart. Einen richtigen kriegt man 
nur durch ziehen des Netzsteckers wieder hin. Oder man trägt 
softwaremäßig die Initialisierung ein.
Übrigens wollte ich damals wissen wie es geht. Deshalb kein Z9001, 
sondern AC-1, LC-80, Z-1013. Letzterer mit ROM-Bank, 256K RAM, eigener 
Monitor (damit ist nicht der BS gemeint), TDL-Basic, Gens-Assembler usw.
Alles nicht von der Stange, da mußte man schon im Gegensatz zu Z9001 
o.ä. ein paar graue Zellen opfern.

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

heute kam sie an, die "Special Edition Retro CPU" mit Firmenaufdruck. 
NMOS und wird schön warm :-)

Gruss,
Christian

Autor: soul e. (souleye)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Retro" mit Datecode von 1999?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Jo. Und genau deswegen sprach Winfried von einem Flag im RAM. Weil RAM
> damals das einzige war, wo man sowas ablegen konnte. Und natürlich
> bringt das seine eigenen Probleme mit sich. Z.B. daß so ein Flag nach
> dem Kaltstart auch zufällig im RAM stehen kann.

Luxusproblem. ;-)

Über solche Probleme stolpert man nämlich erst, wenn man - faul wie man 
trotz Retro ja doch ist - statt einer Handvoll 4116 DRAMs modernere 
SRAMs verwendet.

Bei DRAMs konnte man sich nämlich ziemlich drauf verlassen, dass nach 
ausreichend langer Zeit ohne Strom ein sinnvoll gewähltes Flag im RAM 
nicht den Warmstart-Wert enthält. Da war kein Zufall am Werk, sondern 
bloss ein paar Kondensatoren.

Zumindest wenn man die Möhre nicht in der Tiefkühltruhe betrieben hat. 
Je kälter die Umgebung desto wärmer der Start. ;-)

PS: Wenn man in der Geschichte noch weiter zurück geht, also vor die Ära 
des Z80 und der Halbleiter-RAMs, dann wird das noch interessanter. Da 
brauchts zwingend eine Unterscheidung zwischen Kalt- und Warmstart per 
Schalter, sonst wird das nie was. Ringkernspeicher war nicht-volatil.

: Bearbeitet durch User
Autor: kennt Route_66 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael_ schrieb:
> TDL-Basic,

Hallo!
Leider habe ich mein handkommentiertes Disassembler-Listing irgendwo 
verlegt oder weggeworfen. Bevor ich noch aus dem 12K Maschinencode die 
restlichen Fehler gefunden hatte, war BASIC nicht mehr ganz so wichtig 
für mich.
Es war aber erstaunlich leistungsfähig und umfangreich. Die 
Programmierer von von Technical Design Labs hatten eine Reihe von Tricks 
verwendet, um die Relokation (assemblieren für einen anderen 
Speicherbereich) zu erschweren.
Das Reinspringen, mitten in sonst vernünftige Drei-Byte-Befehle, war so 
ein Trick.

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas hier?
; This is the commented BASIC listing of the 
; TDL 12K Extended "Zapple" BASIC, 
; by Roger Amidon and Neil Colvin, May 1977
;
; This was produced by IDA disassembler
; and further modified for readability (macros and long symbols)
; note this is, although it looks like, not correct Z80 assembler
; to be directly fed into an assembler program - mainly because
; many symbols are too long for Z80 assemblers
; use this as reference only, rather use the HEX dump
; to produce a binary.
;
; The HEX dump has been compared with this commented file;
; while commenting, several OCR errors were corrected.
;
; The hex dump was produced from the book
; Rolf-Dieter Klein, Basic-Interpreter, Franzis Verlag M<FC>nchen, 1982;
; in German language, ISBN 3-7723-6941-3
; The book author himself mentions in the book that he published
; the hex dump because "Der Interpreter wurde urspruenglich von
; TDL (Technical Design Labs) entwickelt und ist sehr leistungsfaehig.
; Da die Firma nicht mehr existiert, soll durch den Abdruck des Listings
; dem Leser die Moeglichkeit gegeben werden, Zugang zu diesem Basic zu
; erhalten." (Seite 103) (Translation: the interpreter was developed
; originally by TDL (Technical Design Labs) and is very powerful.
; Because the company is no longer in existance, the reader is given
; the chance, by printing this listing to get access to this Basic).
;
; The work of reverse engineering and commenting was done by Holger Veit,
; 2012 - this whole work is published unter Creative Commons License
; CC-BY-SA http://creativecommons.org/licenses/by-sa/3.0/

;--------------------------------------------------------------------

;****************************************************************
; some macro definitions for readability
CPHL_DE         macro
                ld    a, h
                sub   d
                jr    nz, @@1
                ld    a, l


Da kann ich glaube ich helfen...

http://www.tiffe.de/Robotron/Zapple-Basic/

Gruß,

Holm

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holm Tiffe schrieb:
> Da kann ich glaube ich helfen...
>
> http://www.tiffe.de/Robotron/Zapple-Basic/
>
> Gruß,
>
> Holm

und wie benutzt man diesen basic interpreter? muss man den an ein 
terminal anbinden? wie speichert er den quelltext usw?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> und wie benutzt man diesen basic interpreter? muss man den an ein
> terminal anbinden? wie speichert er den quelltext usw?

Doku ist doch dabei. Fernschreiber mit Lochstreifen-Stanzer/Leser waren 
damals gleichermassen Terminal, Drucker und Massenspeicher. Manche 
Bastler verwendeten auch alte Telex-Geräte mit dem eigentümlichen 5-Bit 
Baudot-Code, weil die hierzulande leichter zu kriegen waren als 
ASCII-Geräte.

Das Basic arbeitete wie damals häufig über eine Sprungleiste, d.h. die 
Schnittstelle ist anpassbar. Das Arbeitsprinzip freilich nicht.

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok.

Dachte man könnte den Quelltext in einen Speicherberei laden und er 
zieht sich dann Zeile für Zeile rein. Dann müsste man nur noch die 
putchar Funktion anpassen und hätte eine Ausgabe.

Autor: Michael_ (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
kennt Route_66 schrieb:
> Hallo!
> Leider habe ich mein handkommentiertes Disassembler-Listing irgendwo
> verlegt oder weggeworfen. Bevor ich noch aus dem 12K Maschinencode die
> restlichen Fehler gefunden hatte, war BASIC nicht mehr ganz so wichtig
> für mich.

Ja, einige Zeit später war ich stolzer Besitzer eines 286/12 mit 
Hercules.
Ich hab aber meine Mappe wiedergefunden.
Im ersten Bild ist der Anfang des Listings vom TDL. Vielleicht weiß 
jemand die Quelle. Wenn es rechtliche Probleme gibt, bitte löschen.
Es stimmt mit dem ZAPPLE überein. Warum hieß das dann so?
Über die Sprungtabelle und Änderungen des Codes hab ich es an den Z-1013 
angepasst. Es lief dann prima.
Die Abspeicherung hab ich dann zuletzt mit dem Header-Save von Brosig 
gemacht.
Als Beispiel, wie mühsam es damals war, hab ich noch zwei Bilder 
angehängt.
Per Hand analysiert und so Änderungen auch eingepflegt.
Ohne Assembler! Drucken konnte ich auch schon mit einer S3004 Typenrad 
-Schreibmaschine. Da mußte man aber rausgehen und die Tür schließen, 
wenn die losgehämmert hat.

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
So,

auch bei mir geht es weiter, klappte auf Anhieb die Anzeige und auch die 
Port Ansteuerung. Geht rihtig gut mit dem SDCC wenn man sich mit putty 
ein Terminal zum Cubietruck Linux Rechner öffnet, wo der Z80 Code per 
Bash Script kompiliert wird, dann Notepad ++ für den Source über das 
Samba Laufwerk und den Brenner, der sich sofort jeden veränderten Code 
automatisch reinzieht. Der TOP853 taugt schon. Nur jetzt mit 28C64B 
EEPROM statt der EPROM, das nervt doch zu sehr mit dem Löschen. Gebe 
gerne so rund 20 Stück ab. Schon schön, wie man Hardware einfach 
einmappen kann, reicht ein 8-fach D-Flip Flop dazu und schon hat man 
eine Portweriterung.

Der I/O Bus, die Select Ausgänge des Demuxers und Ints sowie die Ports 
werdenn noch hinten über Pfosten herausgführt, eine Erweiterungsplatine 
ist schon in der Planung, die noch ein bisschen mehr Spielkram drauf 
haben wird.

Aber erstmal den STI Baustein anschliessen, die Uart und Timer zu Laufen 
kriegen, damit ich Interrupts habe (muss in Asm gemacht werden, der SDCC 
kann das nicht) und eine Kommunikation mit dem PC herstellen.

Das unten stehende Programm erzeugt 468 Bytes Code. Nur printf, sprintf 
sollte man nicht verwenden, dann explodiert der Code regelrecht.

Evtl. werde ich doch noch 16kb einplanen und das RAM ein wenig kürzen 
auf 48kb. Eine Leitung ändern reicht ja.

#include <asm/z80/features.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#include <string.h>

#include "main.h"


const char digits[11]= {0xc0,0xf5,0xa8,0xb0,0x95,0x92,0x92,0x82,0xf4,0x80,0x90};


// PIO 8255 Special I/O
__sfr __at 0x20 PIO8255_PORT_A;
__sfr __at 0x21 PIO8255_PORT_B;
__sfr __at 0x22 PIO8255_PORT_C;
__sfr __at 0x23 PIO8255_CNTRL;

// ADC 0804
__sfr __at 0x40 ADC0804_READ;

// 7b Segment
__sfr __at 0x60 SEG7;

#define MAX_RAM    40000
uint8_t ram[MAX_RAM+1];

// NMI Interrupt Handler
void cv_vint(void)
{
  __asm
     halt
  __endasm ;
  
}

// Halte CPU an und lasse LED leuchten
void stop_cpu()
{
  __asm
     halt
  __endasm ; 
}

// Setze oder lösche eine LED (0..7) am Port A
// Input: Led Nr, HIGH oder LOW
void SetLed(uint8_t lednr, bool stat)
{
  uint8_t foo;
  
  // Read...
  foo = PIO8255_PORT_A;
  // Modify...
  if (stat==TRUE)  // LED ein = Bit LOW
    foo &= ~(1<<lednr);
  else
    foo |= (1<<lednr);
  // Write...    
  PIO8255_PORT_A = foo;
}

// Zeitverzögerung 
void delay(uint16_t cnt) {
  volatile uint16_t k;
  for (k=0;k<cnt;k++);
}

/*
  Stelle die Peripheriebausteine ein
*/
void InitHardware()
{
  // 8255: Mode 0: Port A,B,C Output
  PIO8255_CNTRL  = 0x80;     //Mode 0: Port A,B,C Output
  PIO8255_PORT_A = 0xff;
  PIO8255_PORT_B = 0;
  PIO8255_PORT_C = 0;
  
  // 7-Segment ....
  SEG7 = 0xff;
    
  // Interrupts der STI
  
  // STI Multi I/0 Uart
}

int main()
{
  uint8_t n,i;
  uint16_t k;

  InitHardware();
  
  for (n=0;n<10;n++) {
    SetLed(0, HIGH); 
    SetLed(7, HIGH);
    delay(5000);
    SetLed(0, LOW); 
    SetLed(7, LOW);
    delay(5000);
  }  
  delay(20000);
  
  n = 0;
  i = 0;
  while (1) {
  
    SEG7 = digits[i++];  
    if (i>9)
      i=0;
  
    // RAM vollschreiben
    for (k=0;k<MAX_RAM;k++) {
      PIO8255_PORT_A = ~(uint8_t)k;
      ram[k] = n;  
    }  
    // Ram auslesen und darstellen
    for (k=0;k<MAX_RAM;k++) {
      PIO8255_PORT_A   = ~ram[k];
      
    }
     
    n++;
  }
 
}

Autor: Ronny S. (phoenix-0815)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
hoffe bin hier mit meiner Anfrage nicht völlig falsch.

Kennt sich jemand mit dem Elzet 80 System aus und wo man dafür noch 
Unterlagen findet.
Würde mir gerne so ein System oder ähnlich aufbauen (nachbauen).

Leider finde ich fast keine Informationen dazu und eine Anfrage beim 
Hersteller nach alten Unterlagen ist bis jetzt Erfolglos.

Hatte zwar Steckkarten dafür in der Bucht gefunden für Preise wo man ins 
grübeln kommt und 2 Seiten wo auch über dieses System nach Schaltplan 
und Unterlagen gesucht wird.

Gruß und Danke Ronny

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte nochmal zu meinem Projekt nachfragen wie es denn mit der 
Treiberleistung des Z80 ausschaut?

Aktuell hängen am Datenbus

- RAM
- ROM
- STI Multi I/O
- ADC Konverter
- 8255 PIO
- 74HCT274 Latch

gefühlt ist das schon recht viel.

Es sollen auf einer weiteren Karte noch mehr Bausteine dazu kommen, vor 
allem Portexpander und ein weiterer Timer Z80 CTC Baustein

Muss ich dann zb einen 74LS640 bidir. Octal Bustreiber zur Entkopplung 
einsetzen?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> ich möchte nochmal zu meinem Projekt nachfragen wie es denn mit der
> Treiberleistung des Z80 ausschaut?

Das Thema hatten wir oben schon abgehakt. Erinnerst du dich an das Bild 
der grossen Platine mit 19 ICs am Bus, aber keinem einzigen Bustreiber?
Beitrag "Re: Retro Fieber: Z80 oder 68000 ?"

An den Datenbus zwischen CPU und Rest gepackt würde ein einzelner 
Treiber bei besagter Platine beim Lesen 18 Lasten auf 18 Lasten 
reduzieren ;-).

: Bearbeitet durch User
Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Muss ich dann zb einen 74LS640 bidir. Octal Bustreiber zur Entkopplung
> einsetzen?

Ich habe bei mir zwischen Z80 und Bus zwei 74LS243 (Datenbus) und drei 
74LS244 (Adress- und Steuerleitungen) gesetzt, aber wahrscheinlich ginge 
es auch ohne. Nachteil: DMA von hinter den Bustreibern geht damit nicht 
mehr, weil die Steuerleitungen nicht von der Peripherie getrieben werden 
können. Das kann man zwar vermeiden, ist aber nicht ganz trivial von der 
Logik. :-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:
> Ich habe bei mir zwischen Z80 und Bus zwei 74LS243 (Datenbus) und drei
> 74LS244 (Adress- und Steuerleitungen) gesetzt

Wenn das die einzigen Treiber sind, dann ist der Effekt auf den Datenbus 
gleich Null. Denn beim Lesen müssen Speicher und IO-Bausteine genauso 
viele Lasten treiben wie ohne Treiber.

Solche Treiber ergeben sich ganz natürlich, wenn der Kram auf allerlei 
Platinen verteilt ist und in einer Backplane steckt. Dann hat jede 
Platine ihren eigenen Treiber zur Backplane. Ist alles auf einer 
Platine, dann ist ein einzelner Datenbustreiber ziemlich sinnarm.

Treiber für Steuerleitungen und einen Teil der Adressleitungen können 
dann zwingend werden, wenn etliche TTLs dran hängen (Dekoder, Logik, 
...) und die statische Last der betreffenden Leitungen zu gross wird, 
also der Strom. NMOS und CMOS Bausteine hingegen stellen keine statische 
Last dar, nur eine kapazitive. Da ist es also eine Frage des Timings, 
und man darf raten, ab wieviel Bausteinen die stärkeren Treiber eines 
74LS244 mehr Zeit einsparen als die Durchlaufzeit dieses Bausteine an 
Zeit kostet.

> Nachteil: DMA von hinter den Bustreibern geht damit nicht
> mehr, weil die Steuerleitungen nicht von der Peripherie getrieben werden
> können. Das kann man zwar vermeiden, ist aber nicht ganz trivial von der
> Logik. :-)

Aus der Hüfte geschossen hätte ich gesagt, /BUSAK schaltet die Treiber 
der CPU ab, wenn der DMA auf Seite der Peripherie platziert wird. Und 
wenn du den DMA Controller auf der CPU-Seite deiner Treiber platzierst, 
damit der DMA auch von denen profitiert, dann schaltet dessen /CS den 
Datenbustreiber ab und das wars. Denkfehler?

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

danke für die Info, dachte ich mir insgeheim auch schon. Und eine 
Backplane gibt es ja nicht, nur eine aufsteckbare Zusatzplatine.

Dann werde ich mich mal mit dem Mode 2 Ints befassen und wie ich die dem 
sdcc compiler beibringe, der dafür nichts an Bord hat und wie ich meine 
auch der schlechtest dokumentierte Compiler überhaupt ist. 
Glücklicherweise hat er in der crt0.s die Möglchkeit Startup Code in Asm 
zu hinterlegen und kann auch inline asm verarbeiten (wobei schon 
Fehlermeldungen kommen, wenn man eine Variable von Asm aus adressieren 
will, die lokal ist und nicht global, zb einen Funktionsparameter.

Ich bin noch nicht über Seite 50 in dem Zaks Buch aber soweit ich das 
verstehe kann der Mostek STI verschiedene Ints auslösen und ist 
kompatibl zum Z80.

Ist dieser Gedankengang richtig?

Der Z80 des Z80 wird mit "IM2" auf Mode 2 gestellt, das I Register mit 
dem Hibyte einer Adresse geladen zb 0x0080. Da der SDCC nur ROM Code 
erzeugen kann muss sich, sagen wir bei 0x0080 eine Tabelle befinden, die 
auf gerade Sprungadressen im ROM verweist.

zb

.org 0x80
   jp int_1
   jp int_2
   jp int_3

usw.

Jezt frage ich mich gerade, da das Datenblatt des STI doch sehr intensv 
studiert werden muss, ob die zurück gelieferten Vektoren der 16 
Interrupts fix sind also zb 0...15 oder ich dem STI noch beibringen 
muss, welche Vektoren er zurück liefert? Es liest sich so, dass er seine 
16 Ints auf 4 Bits abbildet und ich die oberen selbst einstellen kann.

Das Ganze müsste natürlich vorher genau ausgerechnet werden, damit die 
Ints auch ihr Ziel "treffen" und wie ich vermute kann der sdcc wohl 
nicht dazu bewegt werden Funktionen auf feste Plätze zu legen, sondern 
der klatscht sie alle hintereinander.

Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> gefühlt ist das schon recht viel.

Praktisch aber nicht. Denn das was du heutzutage an den Bus hängst, ist 
alles CMOS und braucht so gut wie keine Treiberleistung, verglichen mit 
dem nMOS-Krempel der früher üblich war.

Kritischer sind die Lastkapazitäten. Sowohl durch die Eingänge der 
getriebenen IC als auch durch die Verdrahtung. Das wird sich so 
bemerkbar machen, daß dein System oberhalb einer gewissen Taktfrequenz 
instabil wird.


XL

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Ich bin noch nicht über Seite 50 in dem Zaks Buch aber soweit ich das
> verstehe kann der Mostek STI verschiedene Ints auslösen und ist
> kompatibl zum Z80.

Ja.

> erzeugen kann muss sich, sagen wir bei 0x0080 eine Tabelle befinden, die
> auf gerade Sprungadressen im ROM verweist.

Das ist eine Vektortabelle, 16 Bits pro Zieladresse, keine Sprungleiste. 
Also sinngemäss
  struct {
    void (*vec0)(void);
    void (*vec1)(void);
    void (*vec2)(void);
    ...
    void (*vec127)(void);
  };

> welche Vektoren er zurück liefert?

Ebendies. Jeder Z80 Device, das direkt den IM2 unterstützt, enthält eine 
Register, das den verwendeten Vektorbereich definiert.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Praktisch aber nicht. Denn das was du heutzutage an den Bus hängst, ist
> alles CMOS und braucht so gut wie keine Treiberleistung, verglichen mit
> dem nMOS-Krempel der früher üblich war.

In einem Retro Thread ist der Begriff "heutzutage" etwas unpassend und 
er hat folgerichtig etlichen NMOS Kram auf der Platine. Aber NMOS hat 
auch doch auch bloss MOS-Gates am Eingang, anders als TTLs. 
Unterschiedlich ist die Charakteristik der Ausgänge.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:

> Das ist eine Vektortabelle, 16 Bits pro Zieladresse, keine Sprungleiste.
> Also sinngemäss
>   struct {
>     void (*vec0)(void);
>     void (*vec1)(void);
>     void (*vec2)(void);
>     ...
>     void (*vec127)(void);
>   };


Noch schöner wäre es, wenn es möglich wäre ein

.org 0x0080 vor diesen Struct zu setzen, wenn er als const definiert 
würde. Aber das geht leider nicht.

>> welche Vektoren er zurück liefert?
>
> Ebendies. Jeder Z80 Device, das direkt den IM2 unterstützt, enthält eine
> Register, das den verwendeten Vektorbereich definiert.

Da das STI das einzige Z80 Bauteil ist böte sich demzufolge an, die frei 
definierbaren Bits auf 0 zu setzen.

Langsam wird es interessant :-)

Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Der Z80 des Z80 wird mit "IM2" auf Mode 2 gestellt, das I Register mit
> dem Hibyte einer Adresse geladen zb 0x0080.

Und schon falsch.

Die Tabelle startet immer bei einem Vielfachen von 0x100. 0x0080 ist 
also gar nicht möglich. 0x0400 wäre möglich. Ins I-Register müßte dann 
eine 0x04 geschrieben werden.

> Da der SDCC nur ROM Code
> erzeugen kann muss sich, sagen wir bei 0x0080 eine Tabelle befinden, die
> auf gerade Sprungadressen im ROM verweist.

Ja. Adressen

> zb
>
> .org 0x80
>    jp int_1
>    jp int_2
>    jp int_3
>
> usw.

Nein. Das erzeugt keine Liste von Adressen (2 Byte pro Eintrag) sondern 
eine Liste von Sprungbefehlen. Das sind immer 3 Byte pro Eintrag: ein 
Byte Opcode 0xC3 und dann zwei Byte Adresse.

> Das Ganze müsste natürlich vorher genau ausgerechnet werden, damit die
> Ints auch ihr Ziel "treffen" und wie ich vermute kann der sdcc wohl
> nicht dazu bewegt werden Funktionen auf feste Plätze zu legen, sondern
> der klatscht sie alle hintereinander.

Das macht man in C auch anders. Stichwort Funktionszeiger (Artikel 
Funktionszeiger in C). In Assembler würde man einfach die Label für 
die Einsprungpunkte der Funktionen referenzieren.

Da C vorinitialisierte Variablen kennt, würde man für die Interrupt- 
Vektortabelle einfach ein Array VoidFnct[256] anlegen, mit den Adressen 
(= Funktionspointern) für die ISR initialisieren und das Array fest auf 
die gewünschte Adresse der Vektortabelle binden. Dann legt der Compiler 
die initialen Daten ins ROM und der Startupcode kopiert sie ins RAM.

In Assembler würde man eher die Tabelle einmal löschen und dann die 
handvoll Einträge die man braucht händisch überschreiben.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Da das STI das einzige Z80 Bauteil ist böte sich demzufolge an, die frei
> definierbaren Bits auf 0 zu setzen.

Wenn du die Tabelle nach 0x0080 legen willst, was durchaus geht, dann 
wärs besser, wenn du die Vektoren auch passend nutzt. Denn beim STI sind 
die IM2 Adressbits A4..A7 frei definierbar, und wenn du die alle auf 0 
setzt, dann landest du beim I7 Interrupt auf 0x0000=Reset statt 0x0080.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Die Tabelle startet immer bei einem Vielfachen von 0x100. 0x0080 ist
> also gar nicht möglich. 0x0400 wäre möglich. Ins I-Register müßte dann
> eine 0x04 geschrieben werden.

Doch, das geht. Er braucht ja nur 16 Stück = 32 Bytes, nicht alle 127.
Also I=0 und die Vektoren bei 0x80-0x9F verwenden.

: Bearbeitet durch User
Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> die IM2 Adressbits A4..A7 frei definierbar

Fix: A5..A7.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Vektortabelle einfach ein Array VoidFnct[256]

Sind nur 128.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Praktisch aber nicht. Denn das was du heutzutage an den Bus hängst, ist
> alles CMOS und braucht so gut wie keine Treiberleistung, verglichen mit
> dem nMOS-Krempel der früher üblich war.

Abgesehen vom CLOCK Pin sind die Lasten bei NMOS und CMOS Version der 
Z80 CPU exakt gleich definiert. 5pF pro Eingang, 15pF pro Ausgang (inkl. 
bidirektionale Pins).

Das Timing spezifiziert Zilog für eine Last von 100pF, und zusätzliche 
10ns pro zusätzliche 50pF Last, bis zusätzliche 100pF für 
Adressen/Steuerleitungen und 200pF für Datenleitungen. Wobei man aber 
nicht nur die Pins rechnen darf, die Verdrahtung zählt mit - Daumenregel 
100pF/m, aber ob das auch auf Fädeltechnik mit dem extrem geringen 
Abstand benachbarter Leitungen zutrifft kann ich nicht sagen.

Da ein SN74LS243 Treiber 12ns kostet ist man noch bei einer Buslast von 
insgesamt 150pF ohne Treiber schneller als mit.

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

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Axel Schwenke schrieb:
>> Die Tabelle startet immer bei einem Vielfachen von 0x100. 0x0080 ist
>> also gar nicht möglich. 0x0400 wäre möglich. Ins I-Register müßte dann
>> eine 0x04 geschrieben werden.
>
> Doch, das geht. Er braucht ja nur 16 Stück = 32 Bytes, nicht alle 127.
> Also I=0 und die Vektoren bei 0x80-0x9F verwenden.

Ja. Dann liegt aber nicht die Tabelle bei 0x0080, sondern nur der erste 
genutzte Eintrag. Kleiner aber feiner Unterschied.


XL

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Da ein SN74LS243 Treiber 12ns kostet ist man noch bei einer Buslast von
> insgesamt 150pF ohne Treiber schneller als mit.

Bei komplettem Treibersatz, also Adress-, Steuer- und Datenleitungen hat 
man diese 12ns gleich zweimal an der Backe.

Bei der grossen Platine mit rund 300pF am Datenbus musste eben etwas 
Reserve ins Timing rein, aber man war grad noch innerhalb von Zilogs 
Limit.

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:

> Wenn du die Tabelle nach 0x0080 legen willst, was durchaus geht, dann
> wärs besser, wenn du die Vektoren auch passend nutzt. Denn beim STI sind
> die IM2 Adressbits A4..A7 frei definierbar, und wenn du die alle auf 0
> setzt, dann landest du beim I7 Interrupt auf 0x0000=Reset statt 0x0080.

Also das kann irgendwie nicht sein, ohne mir jetzt I genau angeschaut zu 
haben.

I gibt das MSB vor, also schonmal etwas was ICH ihm sage, also zb 
Tabelle bei 0x100. Das IO gibt den Rest vor, also 3 wählbare Bits und 4 
für die 16 Ints.

Ergo

Zieladresse = I-Reg + (3 Bits vom STI) + (Interrupt Nummer)

Kämpfe grad damit, bin nicht so fit in "Spezial-C", dass ich jetzt 
gleich die richtige Syntax für Zeiger auf Funktionen wüsste, die noch 
als const abgelegt sind. Klappt aber laut Hex Dump so auch. Es wird eine 
Tabelle erzeugt, die die Adresse der C Routinen enthält, wenn ich mir 
das Hex Dump anschaue. Nur muss ich wohl jeden Int, auch die die ich 
nicht brauche auf Routinen umlegen, damit keine Löcher entstehen.
;--------------------------------------------------------------------------
;  crt0.s - Generic crt0.s for a Z80
;--------------------------------------------------------------------------


        .module crt0
         .globl  _main
    .globl  _nmi_vint 
    .globl  _int_sti_gpi_0  ; General Purpose Interrupt 0
    .globl  _int_sti_gpi_1  ; General Purpose Interrupt 1
    .globl  _int_sti_gpi_2   ; General Purpose Interrupt 2
    .globl  _int_sti_gpi_3  ; General Purpose Interrupt 3
    
    
    

  .area  _HEADER (ABS)
  
  ;///////////////////////////////////////////////////////////
  ; Reset vector bei Kaltstart
  .org   0
  jp  init   ;; Sprung in die Init Routine

  ;///////////////////////////////////////////////////////////  
  ;// Mode 1 Interrupt
  .org 0x38
  reti

  ;///////////////////////////////////////////////////////////
  ; NMI Interrupt 0x66, muss mit retn abgeschlossen werden
  .org    0x66
    push af
  push bc
  push de
  push hl
  push iy
  push ix
  call _nmi_vint    ; Aufruf Handler im C Modul main.c
  pop ix
  pop iy
  pop hl
  pop de
  pop bc
  pop af
  retn

  ;///////////////////////////////////////////////////////////
  ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen
  ;.org 0x80
  .dw _int_sti_gpi_0
  .dw _int_sti_gpi_1
  .dw _int_sti_gpi_2
  .dw _int_sti_gpi_3
  
  
init:
  ;; Stack an Spitze des RAM legen
  ld  sp,#0xffff

    ;; Globale Variablen initialisieren
    call  _main    ;; Hauptprogramm aufrufen
  halt

  ;; Ordering of segments for the linker.
  .area _HOME
  .area _CODE
  .area _GSINIT
  .area _GSFINAL
  .area _GSINIT
  .area _DATA
  .area _BSEG
  .area _BSS
  .area _HEAP

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Muss ich dann zb einen 74LS640 bidir. Octal Bustreiber

Ich wusste doch, dass an dem was nicht stimmt... Ok, der geht im Prinzip 
schon. Aber ich schätze dass du bald den Spass dran verlierst, wenn du 
sämtliche Peripherie-Bits und IM2-Vektoren invertiert interpretieren 
musst. ;-)

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In Mode 2, the programmer maintains a table of 16-bit starting addresses 
for every interrupt service routine. This table can be located anywhere 
in memory. When an interrupt is accepted, a 16-bit pointer must be 
formed to obtain the required interrupt service routine starting address 
from the table. The upper eight bits of this pointer is formed from the 
contents
of the I Register. The I register must be loaded with the applicable 
value by the programmer, such as LD I, A. A CPU reset clears the I 
Register so that it is initialized to 0. The lower eight bits of the 
pointer must be supplied by the interrupting device. Only seven bits are 
required from the interrupting device, because the least-significant bit 
must be a 0. This process is required, because the pointer must receive 
two adjacent bytes to form a
complete 16-bit service routine starting address; addresses must always 
start in even locations.

Soviel zum Manual. Boah, dieses zehnmal über die Ecke indirekt indiziert 
denken macht mir nen Knoten ins Hirn :-(

Da ich die Tabelle in der Zeropage liegen habe muss also das I Register 
= 0 sein.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und bevor ich dne Text oben nicht mehr ändern kann, weil der nächste 
Beitrag kommt hier meine Vorstellung:


I = 0x80 setzen, d.h. MSB = 0

STI Vektorregister auf 0, diese 3 Bits da drin

STI löst Interrupt 3 aus und legt "0+3" auf den Bus, also 3

Z80 baut zusammen: I + "3" und landet bei 0x80 + (3 * 2Bytes) = 0x86

Bei 0x86 steht ein Doppelwort, also zb 1234

Z80 führt ein JMP 3412 aus, da zuerst Low, dann High Byte

Soweit ok?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Also das kann irgendwie nicht sein, ohne mir jetzt I genau angeschaut zu
> haben.

Herrje, immer diese Ungläubigen :-)

Vektoradresse:
  A15..A8 = I
  A7..A5  = D7..D5 des PVR vom STI
  A4..A1  = Interrupt-Nummer
  A0      = 0

Wenn du auf 0x80 für den ersten Vektor kommen willst, dann muss 0b100 in 
D7..D5 des PVR.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Z80 baut zusammen: I + "3" und landet bei 0x80 + (3 * 2Bytes) = 0x86

Bloss weil die Z80 CPU so heisst, zaubert die dir keine magischen 0x80 
in die Rechnung. Dein Vektor landet auf 0x0006.

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Bloss weil die Z80 CPU so heisst, zaubert die die keine 80 in die
> Rechnung. Dein Vektor landet auf 0x0006.

Ok, das konnte ich nicht mehr ändern weil du schneller warst. Die 80 
müssen vom STI kommen, was ich aber nicht so dolle finde. Aber über das 
I Reg lassen sich ja nur 0x100er Felder abdecken und bei 8k muss man 
schon etwas sparsam sein zudem der Compiler noch dazu kommt, denn der 
darf den Code nicht plattmachen, er weiss ja nichts von dieser Tabelle, 
wenn ich die erst zur Laufzeit erzeuge bzw einstelle.


>Bei 0x86 steht ein Doppelwort, also zb 1234
>Z80 führt ein JMP 3412 aus, da zuerst Low, dann High Byte
>Soweit ok?

Da ist richtig denke ich mal.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn es dir um Platz geht, dann leg die Tabelle auf die unbenutzten 
Adressen 0x0040-0x005F und definiere PVR[7-5]=0b010 und I=0x00. Ob du 
das nun toll findest oder nicht.

Dein Programm kann dann direkt hinter dem NMI anfangen.

Wenn dir der Platz egal ist, dann nimm 0x0100-0x011F mit PVR[7-5]=0x000 
und I=0x01.

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok,

da ist noch Platz :-)

Auf jeden Fall assembliert er jetzt fehlerfrei durch und auch der C 
Compiler mecker nicht.

        .module crt0
         .globl  _main
    .globl  _nmi_vint 
    .globl  _int_sti_gpi_0  ; General Purpose Interrupt 0
    .globl  _int_sti_gpi_1  ; General Purpose Interrupt 1
    .globl  _int_sti_gpi_2   ; General Purpose Interrupt 2
    .globl  _int_sti_gpi_3  ; General Purpose Interrupt 3

  ;///////////////////////////////////////////////////////////
  ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen
        
  .org  0x80
  .dw _int_sti_gpi_0
  .dw _int_sti_gpi_1
  .dw _int_sti_gpi_2
  .dw _int_sti_gpi_3

Und später im .c File

void int_sti_gpi_0(void)
{

}

void int_sti_gpi_1(void)
{

}
void int_sti_gpi_2(void)
{

}
void int_sti_gpi_3(void)
{

}

Muss das aber noch im De-Assembler kontrollieren.

Ergibt
                            354 ;  ---------------------------------
                            355 ; Function int_sti_gpi_0
                            356 ; ---------------------------------
   0149                     357 _int_sti_gpi_0_start::
   0149                     358 _int_sti_gpi_0:


Also Adresse 0x100 + 0x149 = 0x249

und im Map steht.
 00000249  _int_sti_gpi_0                     main
           00000249  _int_sti_gpi_0_start               main
           0000024A  _int_sti_gpi_0_end                 main
           0000024A  _int_sti_gpi_1                     main
           0000024A  _int_sti_gpi_1_start               main
           0000024B  _int_sti_gpi_1_end                 main
           0000024B  _int_sti_gpi_2                     main
           0000024B  _int_sti_gpi_2_start               main
           0000024C  _int_sti_gpi_2_end                 main
           0000024C  _int_sti_gpi_3                     main
           0000024C  _int_sti_gpi_3_start               main
           0000024D  _int_sti_gpi_3_end                 main


Im Asm Listing aber sind es Nullen. Allerdings assembliert er erst das 
Startup und linked dann alles zusammen, können also auch Platzhalter 
sein.
Sxxxx Assembler V02.00 + NoICE + SDCC mods + Flat24  (Zilog Z80 / Hitachi HD64180), page 2.



   0080                      57   .org  0x80
   0080 00 00                58   .dw _int_sti_gpi_0
   0082 00 00                59   .dw _int_sti_gpi_1
   0084 00 00                60   .dw _int_sti_gpi_2
   0086 00 00                61   .dw _int_sti_gpi_3

Das Hex File sieht dann aber so aus.... wie in dem Bild und 02C9 ist ja 
nicht 0249.

Häh??

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist die Map Tabelle... den NMI setzt er richtig auf 0x137 mit CD 37 
01
aber die

.dw .....

sind falsch.
Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_CODE                               00000100    0000018F =         399. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
           00000100  _stop_cpu                          main
           00000100  _stop_cpu_start                    main
           00000102  _copyright                         main
           00000102  _stop_cpu_end                      main
           00000127  _digits                            main
           00000137  _nmi_vint                          main
           00000137  _nmi_vint_start                    main
           00000139  _InitHardware                      main
           00000139  _InitHardware_start                main
           00000139  _nmi_vint_end                      main
           0000014E  _InitHardware_end                  main
           0000014E  _SetDigit                          main
           0000014E  _SetDigit_start                    main
           00000174  _SetDigit_end                      main
           00000174  _SetLed                            main
           00000174  _SetLed_start                      main
           000001BB  _SetLedByte                        main
           000001BB  _SetLedByte_start                  main
           000001BB  _SetLed_end                        main
           000001CC  _SetLedByte_end                    main
           000001CC  _delay                             main
           000001CC  _delay_start                       main
           000001FA  _LED_Rotate                        main
           000001FA  _LED_Rotate_start                  main
           000001FA  _delay_end                         main
           00000249  _LED_Rotate_end                    main
           00000249  _int_sti_gpi_0                     main
           00000249  _int_sti_gpi_0_start               main
           0000024A  _int_sti_gpi_0_end                 main
           0000024A  _int_sti_gpi_1                     main
           0000024A  _int_sti_gpi_1_start               main
           0000024B  _int_sti_gpi_1_end                 main
           0000024B  _int_sti_gpi_2                     main
           0000024B  _int_sti_gpi_2_start               main
           0000024C  _int_sti_gpi_2_end                 main
           0000024C  _int_sti_gpi_3                     main
           0000024C  _int_sti_gpi_3_start               main
           0000024D  _int_sti_gpi_3_end                 main
           0000024D  _main                              main
           0000024D  _main_start                        main
           0000028F  _main_end                          main


Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok, probieren geht über studieren, man muss Klammern setzen, da es ein 
Vektor ist... dann steht das richtige in der Tabelle drin.

;///////////////////////////////////////////////////////////
  ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen

  .org  0x80
  .dw (_int_sti_gpi_0)
  .dw _int_sti_gpi_1
  .dw _int_sti_gpi_2
  .dw _int_sti_gpi_3

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachwort:

So, ich habe jetzt ein komplettes Programmgerüst für den SDCC Compiler 
für Z80 "Minisysteme" mit Nutzung der Interrupts, die mit einigen 
Workarounds eingebaut wurden, da der sdcc sie nicht unterstützt bzw nur 
marginall, zb durch __interrupt oder __naked Pragmas, die die 
Coderzeugung beinflussen.

D.h. wenn jemand Spass an sowas hat aber weniger Assembler programmieren 
will oder nur da wo es nötig ist kann er von mir dieses Gerüst haben. 
Ich entwickle es noch um einiges weiter, es ist natürlich nur auf den 
STI angepasst und nicht auf andere Bausteine aber nirgendwo im Netz 
finden sich Informationen, die mit google findbar sind, die beschreiben 
wie das zu machen ist. Ich habe da Stunden gesucht, der sdcc ist sowas 
von wenig vertreten und erzeugt doch guten Code wenn man auf die 
Veewendung von Libs verzichtet, denn ein rand() knall mal eben 2000 
Bytes Code dazu, wozu weiss keiner.

Kann man das hier irgendwo ablegen, wenn es fertig ist?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Artikel dazu bauen.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Artikel dazu bauen.

Bin zu blöd ein Wiki zu bedienen, da auch kein Interesse daran. Maixmal 
ein Plaintext File.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Bin zu blöd ein Wiki zu bedienen, da auch kein Interesse daran. Maixmal
> ein Plaintext File.
Von Plaintext zum Wiki-Artikel ist der Schritt u.U. nicht sehr groß.
Fang doch mit dem Textfile als Artikel an, der Rest findet sich dann...

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A.K. !!!!!!!!!!!!!!!!!!

Hilfe..... du hast mir doch den MK3801 empfohlen und den studiere ich 
jetzt grad mal näher.

Hallo Baudrate? Der kann doch wohl nicht nur 1:1 und 1:16? Ich brauche 
ujnbedingt den async Mode, da ich nur USB Umsetzer habe und möglichst 
die bekannten Baudraten fahren will.

Das steht nichts weiter von einem Prescaler drin......

Und alles ist schon eingebaut...

Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Wenn das die einzigen Treiber sind, dann ist der Effekt auf den Datenbus
> gleich Null. Denn beim Lesen müssen Speicher und IO-Bausteine genauso
> viele Lasten treiben wie ohne Treiber.

Ja, aber dafür müssen dann die Einsteckkarten selbst sorgen. Die Treiber 
sitzen auf der Hauptplatine vor den Steckplätzen (und die Chips auf der 
Hauptplatine werden vom Z80 selbst gestrieben).

> NMOS und CMOS Bausteine hingegen stellen keine statische
> Last dar, nur eine kapazitive.

NMOS braucht einen konstanten Stromfluss, um low-Pegel zu halten?

> Aus der Hüfte geschossen hätte ich gesagt, /BUSAK schaltet die Treiber
> der CPU ab, wenn der DMA auf Seite der Peripherie platziert wird. Und
> wenn du den DMA Controller auf der CPU-Seite deiner Treiber platzierst,
> damit der DMA auch von denen profitiert, dann schaltet dessen /CS den
> Datenbustreiber ab und das wars. Denkfehler?

Klingt logisch, aber ich habe ein paar Design-Entscheidungen getroffen, 
die das trotzdem verhindern. Da ich keine Z80-Peripherie benutze und 
auch sonst alles zu Fuß erledige, sind meine Slots nur I/O-fähig (bis 
auf den einen, wo der Speicher drin steckt) und der einzige DMA-Master 
sitzt auf der Hauptplatine. Einen DMA-Controller habe ich nicht. Beim 
nächsten Mal denke ich an dich. ;-)

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nochmal meiner einer:


Ich sehe da nur eine Rettung bei dem Mostek 3801, man ja kaum mehr einen 
Suporter fragen kann:

Timer C oder sind kastriert, können nur Delay. Ich vermute mal, dass die 
einfach endlos mit dem Prescaler Takt von 0..255 rennen und dann von 
vorn. Capture/Compare war ja wohl nicht vorgesehen (ich vermisse schcon 
wieder ARM Timer... der pure Luxus).

Den Ausgang einer dieser Timer dann auf 1:x Teilen und diesen Ausgang an 
den RC und TC der USART gleichermaßen legen, damit die mit dem 
reduzierten Takt rumtackert und man sich irgendwie auf 56700 Baud 
einigt. Das Datenblatt ist so nett und spricht diesen Mode erst gar 
nicht an.

Also muss ich 3.686.400 Hz des System Clock runterteilen / 64 und dann 
taketet er mit 56700 eins weiter. Aber das heisst ja noch nicht, dass 
der Timer Ausgang auch 56700 liefert.

Wann wird der überhaupt gesetzt?  Bei Überlauf von 255 auf 0? Oder 
zählen die wie es beim 8253 üblich war rückwärts und werden mit einem 
Reload Wert vorgeladen, denn sie immer wieder reinladen bei Überlauf? 
Etwas antike Technik....

Au weia....

Gibt aber Leute "Bitsavers", die sogar eine App.note gegescannt haben:

http://schuetz.thtec.org/mccomputer/Mostek%20-%20MK3801%20Application%20Notes.pdf

"Time Constant" scheint der Reload zu sein, 3 ist minimum damit 9600 
baud bei rauskommen.

Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Ich vermute mal

Wie wäre es mit lesen? In der von dir zitierten App Note steht explizit 
drin, inklusive ASM-Schnipsel, wie man Timer C oder D als Baudraten 
Generator verwendet.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:
>> NMOS und CMOS Bausteine hingegen stellen keine statische
>> Last dar, nur eine kapazitive.
>
> NMOS braucht einen konstanten Stromfluss, um low-Pegel zu halten?

Ein NMOS Eingang ist das Gate eines N-MOSFETs. Dass der intern eine 
Stromquelle am Drain hat, statt eines P-MOSFETs wie bei CMOS, das 
beeinflusst nur den Stromverbrauch des Chips.

Bei einem NMOS Ausgang hast du Recht. Der hat eine Stromquelle als 
Pullup. Bei Ausgängen ist die CMOS Version der Z80 daher auch anders 
spezifiziert als die NMOS-Version, wesentlich höherer Source-Strom. Aber 
im Tristate ist diese Stromquelle abgeschaltet (wär ja sonst kein 
Tristate).

: Bearbeitet durch User
Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achso, das wusste ich nicht. Danke für die Aufklärung.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Also muss ich 3.686.400 Hz des System Clock runterteilen / 64 und dann
> taketet er mit 56700 eins weiter. Aber das heisst ja noch nicht, dass
> der Timer Ausgang auch 56700 liefert.

Die UART benötigt wie üblich die 16fache Frequenz am Takteingang. Das 
muss einer der Timer liefern.

Bei mir wars damals 9600 Baud mit Prescaler /4 und Timerwert 4. Andere 
Timerwerte waren 1=38400 und 2=19200. Systemtakt unbekannt, demgemäss 
offenbar 2,4576MHz.

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich hatte das zweite Blatt der App nicht gesehen bzw hing der Reader 
etwas. Also läuft die Baudratenerzeugung auf der letzten Rille bei einem 
Wert von 3 oder 4, Finetuning kann man da vergessen.

Nochmal zurück zu den Timern. Sind die vom 8253/54 abgekupfert? Das 
Mostek Datenblatt ist ja absolut unzureichend. Laufen die Timer also so, 
dass man ins Data Register einen Wert reinschreibt und die zählen dann 
rückwärts bis 0, setzen den Out Pin für einen Zykus HIGH und laden sich 
dann wieder den Startwert aus einem Latch rein? Wie gesagt sind heutige 
Timer deutlich aufwendiger und komplexer und ich erinnere mich nur 
schwach daran was ich mit 17 mal mit dem 8253 gemacht habe.

Nur mal so gefragt: Hat das verkrampfte indirekte Adressieren einiger 
Register einen fertigungstechnischen Grund? Oder gingen denen die Pins 
aus, weil man dafür einen Adressierungspin mehr gebraucht hätte?

Aktuell habe ich ja noch den sdasz80 Assembler, der eine 
"Eigenproduktion" von einem Brian ist und sich leider nicht an gängige 
Konventionen der Syntax hält. Leider ist er Bestandteil des sdcc. UNd 
bisher weiss auch niemand wie man aus einem inline asm Teile Variablen 
des C Teils anspricht.

Allerdings stelle ich auch grad fest dass mans ich aus denb Linux Repos 
eine Version 3.1.0 von 2012 installiert. Zumindest wenn man sdcc auf 
einem A20 (Cubietruck) mit wheezy laufen lässt.

Die Sourcen gibt es ja hier:

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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Also läuft die Baudratenerzeugung auf der letzten Rille bei einem
> Wert von 3 oder 4, Finetuning kann man da vergessen.

Was willst du denn da tunen? Fraktionale Baudratentimer gabs erst 
Jahrzehnte später, in Retro gibts die nicht. 57kbd und 115kbd gab es 
anno STI auch noch nicht. Manch olle UARTs konnten nicht mehr als 19200.

> Nochmal zurück zu den Timern. Sind die vom 8253/54 abgekupfert?

Nicht dass ich wüsste. Ich habe auch nicht den Eindruck, dass die Timer 
des STI sonderlich komplex wären. Und auch nicht, dass Komplexitität 
deine Spezialität wäre. ;-)

> Das Mostek Datenblatt ist ja absolut unzureichend.

Sieh es als frühe Form des Umweltschutzes ;-). Datasheets standen damals 
in Büchern, nicht in PDFs. Dickere Bücher kosteten mehr Bäume.

Betrachte es doch mal als Herausforderung, nicht als Hindernis.

> Laufen die Timer also so,

Probiers halt aus.

> Wie gesagt sind heutige Timer deutlich aufwendiger und komplexer

Du bist ganz sicher, dass du es gerne komplexer hättest? Beim SIO hast 
du eben deshalb die Segel gestrichen und dabei war der deutlich 
einfacher als Zilogs SCC ein paar Jahre drauf. Retro gibts halt nicht 
ohne Retro-Stil. Oder fast nicht. Damals sass man rum, mit dem was man 
hatte, und probierte es im Zweifel eben aus, statt sich jedes Bit per 
Web erklären zu lassen.

> Nur mal so gefragt: Hat das verkrampfte indirekte Adressieren einiger
> Register einen fertigungstechnischen Grund?

Ja. 41-PIN DIP Gehäuse sind sehr selten. ;-)

> Aktuell habe ich ja noch den sdasz80 Assembler, der eine
> "Eigenproduktion" von einem Brian ist und sich leider nicht an gängige
> Konventionen der Syntax hält.

Zugegeben, ich hatte meinen eigenen Assembler und "Compiler". Wie die 
funktionierten wusste ich zufällig. ;-)

Allerdings gehst du mit dem Zwang, sofort unbedingt SDCC statt Assembler 
zu verwenden, den deutlich schwereren Weg eines Zweifrontenkriegs. Zudem 
ist das kein Bisschen Retro.

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:

> Was willst du denn da tunen? Fraktionale Baudratentimer gabs erst
> Jahrzehnte später, in Retro gibts die nicht. 57kbd und 115kbd gab es
> anno STI auch noch nicht. Manch olle UARTs konnten nicht mehr als 19200.

Ich werde mit leben .....müssen.

> Probiers halt aus.

Ich erinnere mich schwach, dass ich Datenbücher aus der Bibliothek holte 
und ansonsten alle möglichen Hersteller anrief, damit sie mir welche 
schicken. Weil Internet... gab es ja nicht :-( Telefonbuch und Auskunft. 
Und bei Firmen schonmal Müllcontainer wo man sich Bücher rausholen 
konnte.


> ohne Retro-Stil. Oder fast nicht. Damals sass man rum, mit dem was man
> hatte, und probierte es im Zweifel eben aus, statt sich jedes Bit per
> Web erklären zu lassen.

Das werde ich gern machen.... ich frage sie ob sie vorwärts oder 
rückwärts laufen :-)

> Zugegeben, ich hatte meinen eigenen Assembler und "Compiler". Wie die
> funktionierten wusste ich zufällig. ;-)

Das ist schon das erste Problem, weil die mehr programmieren als Dokus 
machen. Und wie ich grad mit Schreck festelle zieht sich Debian eine 
andere Version runter als Mint. Aber das liegt eben auch an mir, dass 
ich den ganzen Kram vom PC aus in einem Terminal auf dem Cubie mache und 
das grad umgestellt habe. Und ein Vergleich lieferte 50 Bytes weniger 
Code bei 3.3.0 gegenüber 3.1.,0 und auch einige Macros funktionierten 
plötzlich.

> Allerdings gehst du mit dem Zwang, sofort unbedingt SDCC statt Assembler
> zu verwenden, den deutlich schwereren Weg eines Zweifrontenkriegs. Zudem
> ist das kein Bisschen Retro.

Versteh mich nicht falsch, ich lese das Zaks Buch gern und schaue mir 
auch die Listings mit diesem prähistorischen Gebrabbel an: ld, cpl, in, 
out ... (wer das den ganzen Tag macht wird sicher impotent davon)
aber ein 16 Bit c=a+b tippt sich eben deutlich schneller als

  ld  a,-2 (ix)
  add  a, -4 (ix)
  ld  d,a
  ld  a,-1 (ix)
  adc  a, -3 (ix)
  ld  -6 (ix), d

Genauso mit den EPROMs.. die hier jetzt rumliegen und so schöne Fenster 
haben durch die man die Bits sehen kann ..... habe 3 Flash EEPROM 
gekauft und finde das deutlich entspannter die zu flashen anstatt den 
Toaster wieder rauszuholen und 20 Minuten zu warten bzw die ganze Stange 
erst durchzubrenne bis die Soft läuft und dann 20 EPROMs zu je 5 Stück 
wieder zu löschen.

Nenn es den Sieg des Menschen über die Maschinen :-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Nenn es den Sieg des Menschen über die Maschinen :-)

Oder die Kapitulation des Menschen vor der ihm auf ewig unverständlich 
bleibenden Maschine. ;-)

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Wusstest Du dass der T1000 Terminator auf ner 6510 CPU läuft und dass 
der Code von Steve Wosniak geschrieben wurde auf einem Apple ][ ?

Der war wohl auch "Retro" :-)

Autor: Frank K. (fchk)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Christian J. schrieb:

> aber ein 16 Bit c=a+b tippt sich eben deutlich schneller als
>
>   ld  a,-2 (ix)
>   add  a, -4 (ix)
>   ld  d,a
>   ld  a,-1 (ix)
>   adc  a, -3 (ix)
>   ld  -6 (ix), d

Wer macht denn sowas? ADD HL,rr (rr=BC,DE,HL,SP) existiert.

fchk

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Wusstest Du dass der T1000 Terminator auf ner 6510 CPU läuft und dass
> der Code von Steve Wosniak geschrieben wurde auf einem Apple ][ ?

Immerhin. 1-2 Jahrzehnte lang sahen interaktive Computer-Szenen meist 
irgendwie nach C64 aus.

Wenn du bissel suchst, kannst du vielleicht auch einen 16-Bit 6502 mit 
16MB Adressraum programmieren. Gabs wirklich!

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Wenn du bissel suchst, kannst du vielleicht auch einen 16-Bit 6502 mit
> 16MB Adressraum programmieren. Gabs wirklich!

Seit ich im Netz Seiten fand von Leuten, die sich ihre eigenen CPUs aus 
Gattern und Mikrocode im EPROM aufbauten, was sie der Echtheit auch noch 
hätten weglassen können haut mich nichts mehr um. Sicher wird auch 
irgendeiner bald ne CPU aus einzelnen Transistoren zusammen löten, weil 
er grad geschieden wurde und seitdem zu viel Zeit hat :-)

Da ich mir grad bei wikipedia einiges über das Pipelining moderner CPU 
durchgelesen habe und wie das mit L1 und L2 Cache zusammen wirkt kommt 
mir der Gedanke, dass Assembler keine Chance mehr hat, da ein 
Programmierer sich nun wirklich nicht für das Innenleben einer Super CPU 
interessieren muss um effinzienten Code zu schreiben. Das kann ein 
Compiler besser wenn er weiss wie die Architektur funktioniert, so dass 
zb Pipline Flushes vermieden werden durch geschickte bedingte Sprünge 
usw.

Autor: S. R. (svenska)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
> ich hatte das zweite Blatt der App nicht gesehen bzw hing der Reader
> etwas. Also läuft die Baudratenerzeugung auf der letzten Rille bei einem
> Wert von 3 oder 4, Finetuning kann man da vergessen.

Ein Baudratenquarz macht, dass die Baudrate exakt ist. Was willst du da 
noch tunen?

> Aktuell habe ich ja noch den sdasz80 Assembler, der eine
> "Eigenproduktion" von einem Brian ist und sich leider nicht an gängige
> Konventionen der Syntax hält.

Es gibt keine "gängige Konventionen der Syntax". Jeder Assembler macht 
das anders, und wenn du einen anderen Assembler benutzt als der Autor 
des Buches, dann sind gewisse Dinge halt anders.

Im Gegensatz zum C-Compiler ist der Assembler aber gut dokumentiert. 
Zumindest habe ich mal eine passende ausreichende Doku zu dem gefunden 
und danach das BIOS gebaut.

> Leider ist er Bestandteil des sdcc. UNd bisher weiss auch niemand wie
> man aus einem inline asm Teile Variablen des C Teils anspricht.

Du weißt es nicht. Alle anderen benutzen einfach den Symbolnamen, wie 
bei den großen Compilern auch. Möglicherweise mit Unterstrich davor.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nicht grad Einzeltransistoren, sondern TTLs einschliesslich MSI und 
damit viel moderner als das ausschliesslich aus NORs gebaute Original. 
Aber immerhin komplett ohne Abkürzung per EPROM: 
http://klabs.org/history/build_agc/

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
S. R. schrieb:
> Du weißt es nicht. Alle anderen benutzen einfach den Symbolnamen, wie
> bei den großen Compilern auch. Möglicherweise mit Unterstrich davor.

Das funktoniert aber leider nur bei globalen Variablen. Bei lokalen, 
also dynamisch erzeugten wirft er einen Fehler aus, dass er die nicht 
kennt. Zumindest habe ich es noch nicht mit V3.3.0 ausprobiert. Der _ 
dafür ist bekannt.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Nicht grad Einzeltransistoren, sondern TTLs einschliesslich MSI und
> damit viel moderner als das ausschliesslich aus NORs gebaute Original.
> Aber immerhin komplett ohne Abkürzung per EPROM:
> http://klabs.org/history/build_agc/

Mal kurz quergelesen und ein pdf geöffnet. Das erfordert schon eine sehr 
gute Kenntnis von Computern die weit über das hinaus geht, was man so 
landläufig lernt. Hier ist der Weg das Ziel, denn das Ding kann ja 
faktisch nichts, was nicht jeder AVR heute auch kann, nur eben im Format 
Schrankwand. Also mit maximalem Aufwand etwas Minimales erreichen. Soll 
sicher so athentsich wie möglich sein. Allein die Recherchen die Spec zu 
bekommen dürften endlos gewesen sein.

Nee, lass mal.... habe noch andere Hobbies (Börse und Daytrading), da 
brauche ich meinen Kopf für.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> da ein
> Programmierer sich nun wirklich nicht für das Innenleben einer Super CPU
> interessieren muss um effinzienten Code zu schreiben.

Nur bedingt richtig. Gelebte Praxis aus der näheren Umgebung zeigt, dass 
man ohne Kenntnis der Mikroarchitektur solcher Kisten insbesondere bei 
Multithreading allzu leicht in einige Stolperfallen reinläuft. Das 
behebt sich zwar nicht durch Assembler, aber einfach C/C++/... 
programmieren und das Beste hoffen ist auch nix.

Entsprechendes Lowlevel-Knowhow kann ein Programm ohne Änderung am 
grundlegenden Verfahren um ein Vielfaches beschleunigen. Und da kommt 
immer mal wieder eine Schweinerei dazu. Schau dir mal Haswells 
Transactional Memory an, wo du schon dabei bist:
http://www.realworldtech.com/haswell-tm/
http://www.realworldtech.com/haswell-tm-alt/

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du, bin jetzt weg in die Sauna und noch ne Runde schwimmen im 
Keller-Bad. Hause ja hier in einem völlig leerstehendn Ferienheim :-)

Wie gesagt freue ich mich, dass ich mit Hilfe dieses Forums und viel 
lesen ein Z80 System zum Laufen gekriegt habe statt wie sonst nur ein 
paar AVR zusammen zu pflastern oder einen Arduino, wo ja alles 
funktioniert. Das Boadr zählt grad munter von 0-9 und die LEDs oben 
wandern a la Knight Rider. Das reich erstmal. Muss noch den Mostek 
anschliessen, sind ja auch ca 20 Leitungen ohne die Ports, habe langsam 
Engpässe, da mehr als 3 Drähte in einen Lötpunkt eng werden für die 
Datenleitungen die ja an jedem Chip sind und die kämme sind auch schon 
recht voll, so dass da nichts mehr rein geht und ich quer verdrahten 
muss.

Und danach fange ich den Monitor an denn das Ziel ist es ja Programme 
vom PC in die Kiste zu laden, so dass die Testzeit schneller wird. Muss 
mir da noch was einfallen lassen.

Theorie:

Monitor decodiert Intel Hex File oder alternativ zieht sich das .bin 
rein. Bin scheint einfacher und hex2bin habe ich ja. Wie ich das 
Programm vom PC da rein kriege weiss ich noch nicht. minicom? Terminal 
Programm? Irgendein Protokoll muss da ja auch herhalten. Und PC 
Programmierung habe ich lange nicht mehr gemacht, schon gar nicht unter 
Linux.

Ein cat main.hex > /dev/tty0

wird es sicher nicht tun.

Sprung ins RAM, Code muss natürlich für RAM codiert sein, also andere 
Einstellungen des sdcc.

Bei Reset muss er wissen, dass im Ram was liegt und da rein. Bei 
Stromausfall ist bisher alles weg, habe keinen Pufferakku aber letzlich 
kann auch das ganze Board an eine Batterie dran. Der 3801 säuft sich 
locker 180ma rein, glaube ich dem Datenblatt, also kommen wir für das 
ganze Board mit NMOSs CPU auf fast 500mA und mit CMOs auf maximal 250. 
Derzeit ziehtes nur 60mA incl LEDs.

Und dann wird das ganze irgendeine Anwendung steuern, wo ich mir noch 
was einfallen lassen will.

Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Monitor decodiert Intel Hex File oder alternativ zieht sich das .bin
> rein. Bin scheint einfacher und hex2bin habe ich ja.

Intel Hex bietet dir Prüfsummen an, die du benutzen kannst, um 
Übertragungsfehler zu erkennen. Wenn die fehlerfrei geladen wurde, weißt 
du wenigstens, dass sie auch korrekt angekommen ist.

> Wie ich das Programm vom PC da rein kriege weiss ich noch nicht.

Das könnte vielleicht daran liegen, dass du nicht liest, was dir andere 
schon schrieben. Was soll's, ich wiederhole mich jetzt nicht.

> Bei Reset muss er wissen, dass im Ram was liegt und da rein.

Wozu? Mach in den Monitor einen "Jump to RAM"-Eintrag und gut.

> Und dann wird das ganze irgendeine Anwendung steuern, wo ich mir noch
> was einfallen lassen will.

Eine autonome Steuerung beißt sich sehr stark mit "Anwendung wird als 
Hexdatei ins RAM geladen und von dort gestartet".

Autor: Matthias I. (matze5)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich lese schon eine Weile mit, hab was aehnliches mit den Bausteinen 
oben vor und einige Bücher von Keil über den 8085 und unter anderen Der 
Heimcomputer 8085 hier liegen mit Plänen vom EC 8085 SBC :)

Allerdings fehlen mir noch ein paar Dinge.
Soll evtl. mal mit Altair Basic rennen.

Intressantes Board hast du da, gibts auch Fotos von der aktuellen 
Verdrahtung ?

: Bearbeitet durch User
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

kann Bilder hier nicht einfügen unter Linux, mir fehlt ein Programm zur 
einfachen Größenreduzierung wie vallen jpegger.

Aber die Kommunikation ist simpel, grad mal 20 Minuten zu einlesen

stty raw ispeed 9600 ospeed 9600 -F /dev/ttyUSB0

stellt den USB/Rs232 konverter ein, ggf. noch einige andere Parameter.

echo Hallo > /dev/ttyUSB

schickt auch genau Hallo raus.

und

cat text.text > /dev/ttyUSB

lässt auch auf meinem Raspi genau das erscheinen was in text.txt steht

Easy :-)

PS: Das Keil Buch (grün) habe ich auch seit ca 1986. Habe den 8085 
nachgebaut damals. Habe auch nachgefragt ob sie dazu noch weitere 
Unterlagen haben vor allem die Firmware aber leider keine Antwort.

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Anbei die Bilder.

Oben eine Stiftleiste mit I/O Signalen zur Erweiterung. 2 Ports vom 8255 
in der Wanne.

Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> kann Bilder hier nicht einfügen unter Linux, mir fehlt ein Programm zur
> einfachen Größenreduzierung wie vallen jpegger.

mogrify -scale xx% foo.jpg

(mogrify ist Teil von imagemagick)

Oder pnmscale (aus netpbm). Oder gimp. Oder ...


XL

Autor: Erich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie gesagt sind heutige Timer deutlich aufwendiger und komplexer
Dann sieh' dir mal das Datenblatt des Am9513 an (AMD).
http://www.hartetechnologies.com/manuals/AMD/AM9513.pdf

>9600 Baud
Es gab spezielle Baudrate Generatoren (8116, COM8116, AY5-8116), damit 
konnte man 16 Werte 50 Baud bis max. 19.200 einstellen.

Mit Festfrequenz oder über Steckbrücken geht's auch so 
(http://retired.beyondlogic.org/serial/74hc4060.gif , jedoch Quarz 
5,9152 MHz verwenden.

Gruss

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erich schrieb:
> Mit Festfrequenz oder über Steckbrücken geht's auch so
> (http://retired.beyondlogic.org/serial/74hc4060.gif , jedoch Quarz
> 5,9152 MHz verwenden.

Ich würde 4.9152MHz verwenden. Und 57600/115200bd kann man dann 
vergessen.

Autor: Matthias I. (matze5)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also im grünen Buch von Keil ist doch das Monitorprogramm/Firmware als 
Listening drinnen :)

Sehr schön der Aufbau.

Die Grösse von Bildern reduziere ich immer mit Gimp.

Autor: Ale (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So fieber hatte ich auch, musste es mit hilfe von einem 68008 und einen 
paar 68020 heilen... und platinen :D.

http://propeller.wikispaces.org/pPropQL
http://propeller.wikispaces.org/pPropQL020

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. Mir 24 kannte ich jeden Interrupt des Bios, jeden 
Exe-Header einer Datei, wusste wie eine Fat aufgebaut ist, der TASM war 
mein Freund. Dann kam die dunkle (oder helle?) Zeit ab so 1996 wo ich 
die ersten C-Compiler bekam, Pascal lieben lernte, später kam noch Java 
hinzu und Pearl. Selbst die Bash verlor ihren Schrecken und es enstanden 
Backup Scripte und clvere kleine Programme.

Aber mit 45 breche ich mir einen ab mit DIESEM SCHEISS ASSEMBLER !!!!

Was interessieren mich Flags? Kann es mir nicht sch... egal sein, ob ein 
Carry gesetzt ist oder nicht? Wieso hat das Sch.. Ding nur 8 Bit? Meine 
Zahlen sind größer. Welcher Masochist hat sich das ausgedacht? Und wozu 
brauche ich diese verdammten ' Register im Z80?

Dann fand ich diesen Satz im Internet:

"Assembler ist eine Methode, Programme die zu langsam laufen so 
umzuschreiben, dass sie überhaupt nicht mehr laufen."

Mal wieder etwas ernster:

Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss 
ein Simulator her, damit ich sehen kann, ob er das macht was ich will. 
Es ist mühsam über Jahre eingefleischte Programmiertechniken zu 
vergessen und auf die Grundelemente runter zu brechen. Und erst dann 
setze ich den Code ins Monitor Programm ein. Was kann ich nehmen, um 
etwas komfortabel mit grafischer Oberfläche Z80 Code zu schreiben und 
auszutesten?

Autor: Michael Engel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ale schrieb:
> So fieber hatte ich auch, musste es mit hilfe von einem 68008 und
> einen
> paar 68020 heilen... und platinen :D.
>
> http://propeller.wikispaces.org/pPropQL
> http://propeller.wikispaces.org/pPropQL020

Sehr schöne Projekte - da sowohl der Propeller wie auch diverse 
68k-Cores mittlerweile im Quellcode verfügbar sind, könnte man das ganze 
System sogar auf einen (recht großen) FPGA packen :-).

Hast du vor, die Schaltpläne und den Code irgendwann zu veröffentlichen?

-- Michael

Autor: Icke ®. (49636b65)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Was kann ich nehmen, um
> etwas komfortabel mit grafischer Oberfläche Z80 Code zu schreiben und
> auszutesten?

Guckst du bei Jens Müller:

http://www.jens-mueller.org/jkcemu/

Dieser wirklich gute Emulator wurde für die gängigen Klein- und 
Lerncomputer der DDR entwickelt und enthält auch einen Assembler. Paßt 
zwar nicht direkt zu deinem Hardwareaufbau, hilft aber vielleicht 
weiter.

> "Assembler ist eine Methode, Programme die zu langsam laufen so
> umzuschreiben, dass sie überhaupt nicht mehr laufen."

Pah.. Gejammer von verweichlichten Hochsprachen-Pussies =8P

Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> komfortabel mit grafischer Oberfläche Z80 Code

Mit dem Aufkommen der grafischen Oberflächen kam auch der Abschied vom 
Assembler. Insofern wirst du da kaum fündig werden.

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).

Alternativ kannst du einen Z80 Simulator und deinen PC verwenden.

Wenn es unbedingt ein Eprom Simulator sein soll, gibt es auch dafür 
Bauvorschläge. Mit etwas Lochraster ist das Ding an einem Abend 
aufgebaut.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Wieso hat das Sch.. Ding nur 8 Bit?

Darf ich dich dran erinnern, dass er deine Wahl war? ;-)
Hättest auch eine 68000 CPU nehmen können.

> Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss
> ein Simulator her, damit ich sehen kann, ob er das macht was ich will.

Kann helfen. Wenn du einen findest, der deine serielle Schnittstelle mit 
richtigem CPU Takt und den beiden zugehörigen Drähten simuliert. Denn 
das ist dein primäres Problem.

Denn wenn diese Schnittstelle läuft, dann brauchst du nur einen winzigen 
Bootloader im EPROM, der ab Reset xKB am Stück direkt ins RAM läd und 
anspringt. Ohne Protokoll, ohne Intel-Hex, direkt binär ins RAM ab 
Anfangsadresse.

> Was kann ich nehmen, um
> etwas komfortabel mit grafischer Oberfläche Z80 Code zu schreiben und
> auszutesten?

Editor und Kommandozeile. Retro eben. Herrje, erst muss es Retro sein, 
aber dann mit allem neuzeitlichen Luxus. ;-)

Aber wenn es dich unbedingt danach gelüstet, dann nimm Emacs. Damit geht 
das. Und der ist ausserdem selber schon gut Retro.

: Bearbeitet durch User
Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Icke ®. schrieb:
> Pah.. Gejammer von verweichlichten Hochsprachen-Pussies =8P

Und das von einem Jungspund mit grad mal 45. ;-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Georg G. schrieb:
> Den Monitor an deine Hardware anzupassen ist eine Sache von
> 15 Minuten (maximal).

Deine 15min oder seine? Jeder Monitor braucht eine Schnittstelle nach 
aussen.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:

> Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss
> ein Simulator her, damit ich sehen kann, ob er das macht was ich will.

Hier darf ich mich noch mal kurz einklinken und auf meinen obigen 
Hinweis zurückkommen.

Ein Statisches RAM welches über Bankswitching auf den selben Adressraum 
wie das BIOSROM meines 8 Bit ATARI eingeblendet wurde (huckepack 
aufgelötet) und eine kleine Datenschaufel ab Page ab 0x600 erfüllte 
genau diesen Zweck.

Mit dem Monitor aufgerufen kopierte es mir das BIOS in SRAM und konnte 
on flay zwischen ROM und RAM per SW umschalten. Hier nahm ich meine 
Modifikationen vor und testete sie.

Das setzt  allerdings ein Memorymanager per IOPort und Adressdecoder auf 
das Chipselect vorraus.

Ein Absturz wurde mit einem Reset (nach Möglichkeit im "Warmstart") 
behoben, der Monitor im RAM auf Integrität getestet (Chekcsumme/ 
Biosfunktion im ROM) ansonsten neu geladen und weiter ging es. Das 
dauerte keine 3 Sekunden.
Half das nicht war nach einem Kaltstart alles wieder im grünen Sektor, 
da der Kaltstart immer das ROM einblendet.

Ich hoffe du verstehst jetz meinen frühen Hinweis.

Der Vorteil ist, es erfordert keinen externen Simulator und kann zudem 
später auch als RA(O)MDisk genutzt werden.

Das auf dein Problem zu portieren sollte kein wirkliches Problem sein.
Namaste und viel Spaß

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

Bewertung
1 lesenswert
nicht lesenswert
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

> Was interessieren mich Flags? Kann es mir nicht sch... egal sein, ob ein
> Carry gesetzt ist oder nicht? Wieso hat das Sch.. Ding nur 8 Bit? Meine
> Zahlen sind größer. Welcher Masochist hat sich das ausgedacht?

Ich hätte eigentlich gedacht, daß man sich das 20 Jahren lang merken 
kann. Denn irgendwann mußt du es ja mal gewußt haben.

Außerdem sind ALUs immer zu kurz - genau deswegen gibts ja Carry-Flag 
& Co. Und warst du das nicht, der unbedingt Retro machen wollte?

> 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.

> Dann fand ich diesen Satz im Internet:
>
> "Assembler ist eine Methode, Programme die zu langsam laufen so
> umzuschreiben, dass sie überhaupt nicht mehr laufen."

Typischer Möchtegern-Programmierer-Spruch. Wohl Generation Arduino.

> Da es keinen Sinn macht Code zu testen indem man ein Epom brennt muss
> ein Simulator her, damit ich sehen kann, ob er das macht was ich will.

Dann mach doch. Wenn es für irgendeine Architektur viele Emulatoren 
gibt, dann für den Z80.


XL

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

Bewertung
0 lesenswert
nicht lesenswert
Axel Schwenke schrieb:
> Typischer Möchtegern-Programmierer-Spruch. Wohl Generation Arduino.

In dem Fall wohl Generation WINDOOF


Wenn mich vor zwanzig Jahren etwas nervte dann das Einsetzen des
Versteckens von Funktionen vor dem Anwender mit Ambitionen von 
Standardsoftwareanpssung an eigenene Bedürfnisse.

Ich bin 56 aber das Grundlagenwissen aus der ASM-Zeit hilft mir bis 
heute.

Mein Retrospielzeug heißt TFT Maximite für den ich mir gerade ein 
SW-Programmer für den 93C56 gebastelt habe. Zuvor habe ich allerdings 
schnell mal die IO~ und Touchfunktionen der MMBASICExtension debugged. 
Das ist für mich Urschleim genug.

Und was war der Sinn des ganzen? ... ein EEPROM auf einer 20 Jahre alten 
Liftsteurung zu reinitialisieren leider hatte ich nicht genug Zeit, so 
war ich froh ein orignal EEPROM bestellen zu können (beim Hersteller).
Aber backups werde ich nächstens selbt anlegen können. ;)

Namaste

Autor: Konrad S. (maybee)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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. ;-)

Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Schweizer wieder!

Autor: Michael_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Winfried J. (Firma: Nisch-Aufzüge) (winne) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht 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]

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

Bewertung
1 lesenswert
nicht lesenswert

Autor: Holm T. (holm)
Datum:

Bewertung
2 lesenswert
nicht 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

Autor: soul e. (souleye)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gibt's doch alles: http://www.arduino.cc/

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Winfried was für ein Atari ist das ? 800XL ?

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

: Bearbeitet durch User
Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: soul e. (souleye)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
willst du die Melodieklingel nebenher laufen lassen ;-)

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

Bewertung
0 lesenswert
nicht 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
Autor: heute unangemeldet (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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"

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael_ (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: heute unangemeldet (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Ale (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Schneckenzüchter (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Konrad S. (maybee)
Datum:

Bewertung
0 lesenswert
nicht 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! ;-)

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: bko (Gast)
Datum:

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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Elektrobrazzzler (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Georg G. (df2au)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

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

Namaste

Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht 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.)

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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 !!!

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

Defintionen:
  0x00    IDR   Indirect Data Register
  0x01        GPIP   Purpose I/O Data Register
  0x02    IPRB   lnterrupt Pending Register B
   0x03    IPRA   Interrupt Pending Register A .
  0x04    ISRB   Interrupt -Service Register B
  0x05     ISRA   Interrupt in-Service Register A
  0x06    IMRB   lnterrupt Mask Register B
  0x07    IMRA   Interrupt Mask Register A
  0x08    PVR   Pointer,/Vector Register
  0x09    TABCR   Timers A and B Control Register
  0x0A     TBDR   Timer B Data Register
  0x0B     TADR   Timer A Data Register
  0x0C     UCR   USART Control Register
  0x0D     RSR   Receiver Status Register
  0x0E     TSR    Transmitter Status Register
  0x0F     UDR   USART Data Register  

// Indirekt adressbierbare Register des STI

#define   STI_SCR    0    // Sync Character Register
#define   STI_TDDR  1    // Timer D Data Register
#define    STI_TCDR  2    // Timer C Data Register
#define    STI_AER    3    // Active Edge Register
#define    STI_IERB  4    // Interrupt Enable Register B
#define    STI_IERA  5    // Interrupt Enable Register A
#define    STI_DDR    6    // Data Direction Register
#define    STI_TCDCR  7    // Timer C und D Control Register

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Mit der Infrarot Pistole gemessen.

Ich dachte eher an den Strom.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bart (Gast)
Datum:
Angehängte Dateien:

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

Autor: Bart (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Bart (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Bart (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
Youtube-Video "SymbOS on a MSX TurboR + GFX9000 (1)"

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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! :-)

Autor: A. K. (prx)
Datum:

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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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$

Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

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

Bewertung
0 lesenswert
nicht 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

Autor: Harald N. (haraldn)
Datum:

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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Georg G. (df2au)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Leo C. (rapid)
Datum:

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

man objcopy
man dd

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

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

: Bearbeitet durch User
Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

  ; Tabelle der Mode 2 Int Vektoren auf die Handler Funktionen im C Modul
  ; Reihenfolge beachten !!! Siehe Manual Mostek 3801, Interrupt Tabelle
  .org 0x40
  .dw (_int_sti_gpi_0)
  .dw (_int_sti_gpi_1)
  .dw (_int_sti_gpi_2)
  .dw (_int_sti_gpi_3)
  .dw (_int_sti_timer_d)
  .dw (_int_sti_timer_c)
  .dw (_int_sti_gpi_4)
  .dw (_int_sti_gpi_5)
  .dw  (_int_sti_timer_b)
  .dw  (_int_sti_transmit_error)
  .dw  (_int_sti_transmit_buffer_empty)
  .dw  (_int_sti_receive_error)
  .dw  (_int_sti_receive_buffer_full)
  .dw  (_int_sti_timer_a)
  .dw  (_int_sti_gpi_6)
  .dw  (_int_sti_gpi_7)


Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?
void InitHardware()
{
  // 8255: Mode 0: Port A,B,C Output
  PIO8255_CNTRL  = 0x80;     //Mode 0: Port A,B,C Output
  PIO8255_PORT_A = 0xff;
  PIO8255_PORT_B = 0;
  PIO8255_PORT_C = 0;

  // 7-Segment ....
  SEG7 = 0xff;

  // STI konfigurieren für Uart Ausgabe
  STI_UCR   = 0x88;      // = 10001000  UART Control Register 8N1, DIV16
  STI_RSR   = 0x01;      // RX Status - Enable RX
  STI_TSR   = 0x05;      // TX Status - TX High, TX enabled
  // Timer D...
  STI_PVR   = STI_TDDR;    // Zeiger PVR auf Timer D Data
  STI_IDR   = 0x03;      // Timer D Zeitkonstante
  STI_PVR   = STI_TCDCR;    // Zeiger auf Timer C,D Control Register
  STI_IDR   = 0x89;      // Timer D DIV 4, C = Stop
  // GPIO.....
  STI_PVR   = STI_DDR;    // Zeiger PVR auf indirect 6 (DDR)
  STI_IDR   = 0xff;      // GPIO als Output
  STI_GPIP  = 0x00;      // GPIO auf Null setzen
  // Timer A = endlos Run 
  STI_TADR  = 0xff;      // Reload Wert Timer A
  STI_TABCR = 0x70;      // Timer A DIV 200, 255x200 = maximale Verzögerung
  STI_PVR   = STI_IERA;    // Timer A /RX Buffer Interrupt einschalten  
  STI_IDR   = 0x30;
  STI_IMRA  = 0x30;      // Timer A Interrupt / RX Buffer full unmask
  STI_IPRA  = 0x00;      //Pending Ints löschen
  
  // Zuletzt Interrupt Vektor für Mode 2 laden
  STI_PVR   = 0x40;      // Basisadresse der Ints für crt0.s Tabelle setzen

  __asm            // Mode 2 Interrupt auswählen und Ints einschalten
     im 2
     ei
  __endasm ;

}

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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.

: Bearbeitet durch User
Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

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

Bewertung
0 lesenswert
nicht 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
Autor: Holm T. (holm)
Datum:

Bewertung
1 lesenswert
nicht 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

: Bearbeitet durch User
Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Holm T. (holm)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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:
extern int f(int *x);

int test( int a, int b)
{
  static int drei = 3;
  
  int local;
  
  local = a + b;
  
  return drei + f(&local);
}

Compiler Output:
;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.4.0 #8981 (Jul  5 2014) (Linux)
; This file was generated Thu Oct 30 11:39:18 2014
;--------------------------------------------------------
  .module testpar
  .optsdcc -mz80
  
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
  .globl _test
  .globl _f
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
  .area _DATA
_test_drei_1_3:
  .ds 2
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
  .area _INITIALIZED
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
  .area _DABS (ABS)
;--------------------------------------------------------
; 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
;--------------------------------------------------------
; Home
;--------------------------------------------------------
  .area _HOME
  .area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
  .area _CODE
;testpar.c:3: int test( int a, int b)
;  ---------------------------------
; Function test
; ---------------------------------
_test_start::
_test:
  push  af
;testpar.c:9: local = a + b;
  ld  hl,#6
  add  hl,sp
  ld  iy,#4
  add  iy,sp
  ld  a,0 (iy)
  add  a, (hl)
  ld  d,a
  ld  a,1 (iy)
  inc  hl
  adc  a, (hl)
  ld  e,a
  ld  iy,#0
  add  iy,sp
  ld  0 (iy),d
  ld  1 (iy),e
;testpar.c:11: return drei + f(&local);
  ld  hl,#0x0000
  add  hl,sp
  push  hl
  call  _f
  pop  af
  ld  de,(_test_drei_1_3)
  add  hl,de
  pop  af
  ret
_test_end::
  .area _CODE
  .area _INITIALIZER
  .area _CABS (ABS)

Autor: Eric (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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"?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
 ;///////////////////////////////////////////////////////////
    ; Anordung der Segmente fuer den Linker, ab hier nur relative
    ; Adressen

      .area  _CODE
      .area  _INITIALIZER
      .area  _HOME
      .area  _GSINIT
      .area  _GSFINAL
      .area  _DATA
      .area  _INITIALIZED
      .area  _BSEG
      .area  _BSS
      .area  _HEAP
    
    ;///////////////////////////////////////////////////////////
    ;; ------- Start des Hauptprogramms nach der Zeropage  -----------
    
    .area _CODE
    init:
    
    ld  sp,#stack   ;; Stack an Spitze des RAM legen
    
    ; Teste ob Userprogramm im RAM vorhanden
    ; ....
    
    ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt)
    xor     a             ; clear a and carry
    ld      bc,#0xdfff    ; ram size left
    ld      hl,#0x2000    ; starting from 2000
    ld      de,#0x2001
    ld      (hl),a        ; 0 -> (2000) 
    ldir                  ; (HL) -> (DE)

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

weiter: 

    ; ###### Hauptprogramm aufrufen #######
    jp  _main       

    ; Endlos Schleife
    halt
 endlos:
    jr endlos       ; Sicher ist sicher
    
    ret
       
          
    ; // reserved
      .area _GSFINAL
      ret

Autor: Leo C. (rapid)
Datum:

Bewertung
1 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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."

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Leo C. schrieb:
> Zeigen! (link)

s.o.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

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


Version 2:
;  ---------------------------------
                            367 ; Function SetDigit
                            368 ; ---------------------------------
   01D0                     369 _SetDigit_start::
   01D0                     370 _SetDigit:
                            371 ;driver.c:61: SEG7 = digits[i & 0x0f];
   01D0 21 02 00      [10]  372   ld  hl, #2+0
   01D3 39            [11]  373   add  hl, sp
   01D4 7E            [ 7]  374   ld  a, (hl)
   01D5 E6 0F         [ 7]  375   and  a, #0x0F
   01D7 5F            [ 4]  376   ld  e,a
   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.

Autor: A. K. (prx)
Datum:

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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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
extern int f(int *x);

int test(int pa, int pb)
{
  int local;
  
  local = pa*2 + pb;
  
  return f(&local);
}

Compiliert mit:
$ sdcc -mz80 -S testpar.c --fno-omit-frame-pointer
        .area _CODE
;testpar.c:3: int test(int pa, int pb)
;       ---------------------------------
; Function test
; ---------------------------------
_test_start::
_test:
        push    ix              ;framepointer (fp) der aufrufenden Funktion retten
        ld      ix,#0           ;
        add     ix,sp           ;ix mit stackpointer laden (neuer fp)
        push    af              ;Platz auf Stack für lokale Variable 'local'

;Der Stack sieht jetzt so aus:
;
;       |          | höhere Adressen
;       +----------+
;       | pb       | sp+8    ix+6
;       +----------+
;       | pa       | sp+6    ix+4
;       +----------+
;       | ret-addr | sp+4    ix+2
;       +----------+
;       | ix       | sp+2    ix+0
;       +----------+
;       | local    | sp+0    ix-2
;       +----------+
;       |          | Niedrigere Adressen
;

;testpar.c:7: local = pa*2 + pb;
        ld      l,4 (ix)        ;pa nach hl
        ld      h,5 (ix)
        add     hl, hl          ;pa*2
        ld      e,6 (ix)        ;pb nach de
        ld      d,7 (ix)
        add     hl,de           ;pa*2 + pb
        inc     sp              ;sp auf 'local' zeigen lassen
        inc     sp              ;trotz fp, so gehts schneller
        push    hl              ;hl in 'local' speichern
;testpar.c:9: return f(&local);
        ld      hl,#0x0000
        add     hl,sp           ;addresse von local
        push    hl              ;auf Stack als Parameter für f
        call    _f
        ld      sp,ix           ;locale Variablen vom Stack entfernen
        pop     ix              ;fp der aufrufenden Funktion wiederherstellen
        ret
_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) :(

Autor: Leo C. (rapid)
Datum:

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

Zitat sdcc-Manual:
3.14.2 A Step by Step Introduction

Starting from a small snippet of c-code this example shows for the MCS51 how to use inline assembly, access
variables, a function parameter and an array in xdata memory. The example uses an MCS51 here but is easily
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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:
--reserve-regs-iy 
This option tells the compiler that it is not allowed to use register pair 
iy. The option can be useful for systems where iy is reserved for the OS. 
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Letzteres

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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......

Autor: Leo C. (rapid)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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;
}

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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:
 push  ix
 ld    ix,#0
 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
# Assembliere das crt0 startup file
echo "Assembliere....."
sdasz80 -plosgff -o -l crt0.rel crt0.s
echo "Kompiliere main.c...."
sdcc -mz80 main.c -c
echo "Linke beide Dateien...."
sdcc -mz80 --verbose --no-std-crt0 --vc --code-loc 0x0100 --data-loc 0x2000 crt0.rel main.rel
# In Binaerformazt wandeln
./hex2bin -p 0 crt0.ihx
#echo "Datei zum Target uebertragen..."
#cat crt0.bin > /dev/ttyUSB0
/////////////////////////////////////////////////////////
// Zeichenausgabe für printf auf der STI mit 9600 Baud
void putchar(char c)
{
    while ((STI_TSR & 0x80) == 0);  // Warte bis Buffer frei...
    STI_UDR = c;                    // Byte einschreiben

}

putchar funktioniert schon, getchar auch.

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

gruss,
Christian

Autor: Leo C. (rapid)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:

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

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
    ;; Initialise global variables
        call    gsinit
  call  _main
  jp  _exit

  .area   _CODE
_exit::
  ;; Exit - ddtz breakpoint entry
  rst     0x30
1$:
  halt
  jr  1$

  .area   _GSINIT
gsinit::
  ld  bc, #l__INITIALIZER
  ld  a, b
  or  a, c
  jr  Z, gsinit_next
  ld  de, #s__INITIALIZED
  ld  hl, #s__INITIALIZER
  ldir
gsinit_next:

geht:
  ;///////////////////////////////////////////////////////////
    ;; ------- Start des Hauptprogramms nach der Zeropage  -----------
    
    .area _CODE
    init:
    
    ld  sp,#stack   ;; Stack an Spitze des RAM legen
    
    ; Teste ob Userprogramm im RAM vorhanden
    ; ....
    
    ; Ram ausnullen (auskommentieren, wenn von PC Upload erfolgt)
    xor     a             ; clear a and carry
    ld      bc,#0xdfff    ; ram size left
    ld      hl,#0x2000    ; starting from 2000
    ld      de,#0x2001
    ld      (hl),a        ; 0 -> (2000) 
    ldir                  ; (HL) -> (DE)

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

weiter: 

    ; ###### Hauptprogramm aufrufen #######
    jp  _main       

    ; Endlos Schleife
    halt
 endlos:
    jr endlos       ; Sicher ist sicher
    halt
          
    ; // Hier muss ein ret rein  
      .area _GSFINAL
      ret

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das geht bei mir nicht!

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

Autor: Leo C. (rapid)
Datum:

Bewertung
0 lesenswert
nicht 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ß.

Autor: Christian J. (Gast)
Datum:
Angehängte Dateien:
  • crt0.s (4,9 KB, 93 Downloads)

Bewertung
0 lesenswert
nicht 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.
void to_buffer( unsigned char c )
{
c; // to avoid warning: unreferenced function argument
__asm
; save used registers here.
; 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.

Autor: S. R. (svenska)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christian J. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Leo C. (rapid)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Christian J. schrieb:
> Das geht bei mir nicht!