Terminal-Programme unterstützen üblicherweise die ANSI
Terminalemulation, die sich aus der Definition der DEC VT100 Terminals
ableitet. Also mit Backspace/DEL, Cursorsteuerung etc.
Hi,
lese grad die Scancodes aus, also was der Z80 sieht wenn ich auf den
Tasten klimper... "Pfeil Links" = "D" = 0x44, wie unterscheidet man das
denn dann?
Kann allerdings nicht sehen ob zb 2 zeichen schnell nacheinander kommen,
nur das letzte wird angezeigt und da sind die Codds für die beiden
gleich.
ANSI ist eingestellt.
Da kommen mehrere Zeichen, eine ESC Sequenz.
Scancodes im herkömmlichen sinne sind das auch nicht,Scancodes liefert
eine heute übliche Tastatur und erzählt damit welche Tastennummer
gedrückt oder losgelassen wurde. Buchstaben/Zahlen etc werden vom
Rechner den Scancodes erst später zugeordnet.
Du mußt Folgen von Zeichen die mit ESC beginnen abfangen und einen
Timeout-Mechanismus implementieren.
Gruß,
Holm
Christian J. schrieb:> Ich möchte den Monitor doch schon noch etwas ausbauen und habe mir auch> den Tiny Basic Interpreter besorgt für den AVR, der sich sicherlich> anpassen lassen wird.
Sorry, ich habe das Szenario um Z80, AVR und Minicom noch nicht ganz
verstanden.
Was hat der AVR mit dem Z80 zu tun? Soll der AVR mit dem PC
kommunizieren und von dort via Terminal-Emulation Befehle entgegennehmen
und diese dann an den Z80 weitergeben?
Ich habe da mal eine Art Mini-Curses für den AVR geschrieben, siehe
MCURSES. Mit Hilfe dieser Lib werden über ein paar Dutzend
Funktions-/Cursor- und andere Tasten "verstanden". Ausserdem kann man
damit das Terminal (und den Cursor) gezielt, ansteuern, Positionen
setzen, Scrollen (vorwärts und rückwärts), Attribute setzen usw. - halt
alles, was ein VT102, VT200, VT320 oder VT400 so "versteht".
EDIT:
Im dazugehörenden Thread Beitrag "MCURSES - Mini Curses Bibliothek für Mikrocontroller"
steht auch etwas zur Zusammenarbeit mit minicom, insb. was die
Hardware-Flow-Control Problematik betrifft.
Frank M. schrieb:> Was hat der AVR mit dem Z80 zu tun? Soll der AVR mit dem PC> kommunizieren und von dort via Terminal-Emulation Befehle entgegennehmen> und diese dann an den Z80 weitergeben?
Nein,
ich habe mir nur C Sourcen heraus gesucht, wie zb einen Basic
Interpreter, der nur einen AVR, eine RS232 hat und damit über ein
Terminal zu bedienen ist, so als hacke man in einen C64 Basic ein. Da C
portierbar ist brauhce ich nur die I/O Routinen umzuleiten und da keine
Hardware benötigt wird müsste das auf dem Z80 auch laufen.
Das mit den Esc Sequencen habe ich grad gelesen, der Stndard hat sich
wohl auch mehrfach geändert seit den XT tastaturen. Schwierig, dann
müsste ich zeichenweise durch die Eingabe durch und nicht mehr einfach
bis zum ersten Leerzeichen.
Frank, ich schaue mir das mal an... muss erstmal einen Überblick
kriegen.
Aktuell gehts nur darum:
Z80 nimmt zeichenweise entgegen uns echot das so, dass man wie an einem
normalen Terminal arbeitet. EOL (CR) sendet den String ab. Bewegt der
User die Pfeiltasten muss natürlich der Zeichenpointer auch verschoben
werden. Im Buffer soll immer das stehen, was auch in der sichtbare Zeile
steht.
Christian J. schrieb:> Da C> portierbar ist brauhce ich nur die I/O Routinen umzuleiten und da keine> Hardware benötigt wird müsste das auf dem Z80 auch laufen.
Nunja, bedingt mag das funktionieren.
> Das mit den Esc Sequencen habe ich grad gelesen, der Stndard hat sich> wohl auch mehrfach geändert seit den XT tastaturen.
Das hat weniger mit den XT-Tastaturen eines PCs, sondern eher mit der
Entwicklung des Terminal-Standards VT100->VT102->VT200->VT320->VT400 zu
tun. DAS waren die Terminals der 80er! Mit PC-Tastaturen hatten die
herzlich wenig zu tun. Damals gabe es für PCs auch schon einige wenige
Terminal-Emulationen, welche die oben genannten Standards auch (mehr
schlecht als recht) emulieren konnten. Jedoch mussten immer wieder
Abstriche gemacht werden wegen des doch sehr abweichenden
Tastatur-Layouts (z.B. Anordnung/Funktion der 6 EDIT-Tasten oberhalb der
Cursor-Tasten, Keypad-Tasten PF1 bis PF4, VT200-Funktionstasten F6 bis
F22).
> Schwierig, dann> müsste ich zeichenweise durch die Eingabe durch und nicht mehr einfach> bis zum ersten Leerzeichen.
Das erledigt MCURSES für Dich. Es interpretiert die von der Tastatur
gesandten ESCAPE-Sequenzen und setzt diese in eine Konstante um, z.B.
KEY_DOWN.
Beispiel (kleiner Zeileneditor):
1
uint8_tch=getch();
2
3
switch(ch)
4
{
5
case'a':show_address();break;
6
case'v':show_value();break;
7
caseKEY_LEFT:go_left();break;
8
caseKEY_RIGHT:go_right();break;
9
caseKEY_UP:show_last_line();break;
10
caseKEY_DOWN:show_next_line();break;
11
}
Du erhältst also nicht nur einzelne aphanumerische Zeichen, sondern auch
direkt feste Codes für Funktionstasten. Um die Decodierung der
Escape-Sequenzen brauchst Du Dich nicht mehr zu kümmern - das erledigt
MCURSES für Dich.
> Frank, ich schaue mir das mal an... muss erstmal einen Überblick> kriegen.MCURSES läuft nicht nur auf AVRs, sondern auch auf auf UNIX/Linux.
Der Source ist modular auf Portabilität für andere Plattformen
ausgelegt. Wenn Du das I/O-Interface anpasst (siehe phyio-Funktionen),
sollte es auch auf einem Z80 laufen, da es auf minimalen
Ressourcen-Verbrauch getrimmt wurde.
> Aktuell gehts nur darum:>> Z80 nimmt zeichenweise entgegen uns echot das so, dass man wie an einem> normalen Terminal arbeitet. EOL (CR) sendet den String ab. Bewegt der> User die Pfeiltasten muss natürlich der Zeichenpointer auch verschoben> werden. Im Buffer soll immer das stehen, was auch in der sichtbare Zeile> steht.
Ist mit MCURSES problemlos machbar. Und noch einiges mehr. Du musst
es "nur" auf den Z80 portieren.
Hier noch ein kleines Demo-Programm als Filmchen:
http://www.mikrocontroller.net/wikifiles/e/ed/Mcurses.avi
Trotzdemm zum Verständnis, der Code ist ja auch etwas größer.
RX/TX
Z80 <--------> PC (minicom)
Tastendrücke gehen direkt zum Z80 durch. gets() echot sie allein,
getchar nicht. gets erkennt auch Pfeiltasten und Backspace! D.h. minicom
fährt Cursor zurück uw. Aber im Puffer ist Müll drin, s.h. gebe ich ein
resed, löassche das d dann mit BS und mache ein t draus steht im Buffer
BS usw mit drin. Ärgerlich.
Ich habe
1. getchar und putchar für meine I/0
2. buffer[80] für die Zeichen.
Grundprinzip
do {
Hole Zeichen vom PC
Werte aus und bearbeite Puffer
Echo Zeichen zurück
} while (c!=EOL) // Bis Return Eingaben beendet
- Dann Parser aufrufen um String von Parameter aubzutrennen
- Übergabe Kommando und Parametzer an richtige Unterfunktion
Wo kann ich in diesem Prinzip jetzt Deine Routinen einbauen?
Christian J. schrieb:> Wo kann ich in diesem Prinzip jetzt Deine Routinen einbauen?
Das passt schon alles.
Du passt in mcurses.c die phyio-Funktionen unter Einsatz von putchar()
und getchar() an und benutzt dann in Deiner Anwendung:
addch() statt putchar()
getch() statt getchar()
addstr() statt puts()
move() zum Bewegen des Cursors
attrset() Zum Setzen von Attributen, wie Reverse, Farbe usw.
Ein simples Beispiel:
1
#include"mcurses.h"
2
3
intmain()
4
{
5
unsignedcharch;
6
7
initscr();// init mcurses
8
9
move(11,10);// Cursor an Stelle y=11, x=10 setzen
10
addstr("Hello, World!");
11
12
while((ch==getch())!=KEY_DOWN)// Warten, bis Cursor runter gedrückt wird
13
{
14
;
15
}
16
17
endwin();// end mcurses
18
return0;
19
}
Vielleicht mögen Dir solche Funktionsnamen wie initscr() und endwin()
merkwürdig vorkommen. Ich persönlich hätte sie lieber anders genannt.
Sie sind aber an die (n)curses-LIB von BSD, SYSV-UNIX bzw. Linux aus den
80er/90er angelehnt, siehe auch:
http://de.wikipedia.org/wiki/Curses
So findet sich so manch ein UNIX-Programmierer hier leichter wieder ;-)
P.S.
Das auf Wikipedia aufgeführte Beispiel-Programm benutzt printw() statt
addstr(). printw() ist für die formatierte Ausgabe gedacht - analog zu
printf(), ist aber wg. knapper Ressourcen auf dem µC nicht umgesetzt.
Wikipedia hätte hier besser auch addstr() im Beispiel-Programm benutzen
sollen, da von der Formatierungs-Fähigkeit von printw() im Beispiel
überhaupt kein Gebrauch gemacht wird.
Hallo Frank,
dank Dir erstmal ganz herzlich für deine vielen Infos und dass du das so
ausführlich erklärt hast. Werde heute nachmittag mal einige Tests
machen.
Eine Frage trotzdem noch, wenn ich deinen Routinensatz anschaue:
Muss ich mir selbst eine Schleife schreiben, die die Zeichen einzeln
entgegen nimmt, diese auswertet und entsprechend etwas zurück gibt? Die
schaut ob es ein Pfeil ist und dann den Befehl gibt den Coursor zu
versetzen, die ein BS erkennnt und den Pointer auf den Buffer rück
setzt?
Oder ist das schon "fertig"? Ziel ist ja in einem Satz formuliert:
Im Puffer soll exakt das stehen, was der User am Terminal eingetippt
hat. Und wenn er sich 10 Mal vertippt hat und es korrigiert hat, soll
die Endversion drin stehen aber keinerlei Sonderzeichen.
Christian J. schrieb:> Im Puffer soll exakt das stehen, was der User am Terminal eingetippt> hat. Und wenn er sich 10 Mal vertippt hat und es korrigiert hat, soll> die Endversion drin stehen aber keinerlei Sonderzeichen.
Nein, diese Funktionalität ist nicht umgesetzt (sie entspricht eher der
readline-Bibliothek von Linux), ist aber auch nicht schwierig zu
programmieren.
Was Du möchtest, ist ein Ein-Zeilen-Mini-Editor. Du übergibst einen
Buffer und bekommst den gefüllt wieder zurück - also etwas entsprechend
der stdio-Funktion gets(). Den Mini-Editor dafür hab ich ruckzuck
zusammengestellt. Ich poste hier heute nachmittag den entsprechenden
Code bzw. lege den direkt im MCURSES-Artikel ab.
So, die Funktion getnstr() ist fertig. Auch sie ist angelehnt an die
entsprechende Curses-Funktion, siehe auch:
http://linux.die.net/man/3/getstr
Syntax:
void getnstr (char * str, uint8_t maxlen)
Einlesen eines Strings str, bis CR (ENTER) gedrückt wird - mit
Editierfunktionen.
maxlen ist dabei die maximale Eingabelänge inklusive(!) des
terminierenden '\0'. Will man also maximal 80 Zeichen Input haben, muss
der Buffer als buf[81] definiert sein und maxlen == 81 sein - analog zur
stdio-Funktion fgets().
Weiteres Makro (kommt dann nach mcurses.h):
void mvgetnstr (uint8_t y, uint8_t x, char * str, uint8_t maxlen)
Hier wird erst der Cursor positioniert, dann geschieht die Eingabe.
Beispiel:
1
#include"mcurses.h"
2
3
int
4
main()
5
{
6
charbuf[81];
7
8
initscr();// init mcurses
9
move(10,10);// Eingabe in Zeile 11, Pos 11
10
getnstr(buf,81);// String einlesen
11
mvaddstr(15,10,buf);// Eingabe in Zeile 16 wieder ausgeben
12
endwin();// end mcurses
13
}
Mit folgende Sondertasten kann die Eingabe editiert werden:
Pos1 - KEY_HOME: Sprung an den Anfang des Eingabebuffers
Ende - KEY_END: Sprung an das Ende des Eingabebuffers
Cursor links - KEY_LEFT: Cursor links
Cursor rechts - KEY_RIGTH: Cursor rechts
Backspace - KEY_BACKSPACE: Zeichen links vom Cursor löschen
Entf - KEY_DC: Zeichen unter dem Cursor löschen
Reicht Dir das? Für Einfüge-/Überschreibenmodus habe ich jetzt keine
Lust gehabt. Eingegebene Zeichen werden daher immer eingefügt.
Die Funktion getnstr() hängt im Anhang an - schon mal zum Anschauen. Ich
werde die Download-Datei mcurses.zip im Laufe des heutigen Tages
aktualisieren.
Frank M. schrieb:> Reicht Dir das? Für Einfüge-/Überschreibenmodus habe ich jetzt keine> Lust gehabt. Eingegebene Zeichen werden daher immer eingefügt.
Mundgerechter gehts doch nicht ! :-) Dank dir ganz herzlich, wird heute
umgesetzt !
Die Ringpuffer werde ich allerdings wohl an eine INT Routine anbinden,
da ich die Z80 Uart puffern will, damit kein Zeichen mehr verloren geht
bei Bearbeitungsschritten bzw Decodierung der Strings. Habe schon alles
AVR maessige rausgeworfen und auch die Linux Funktionen, die ich
gefunden habe. Nur getchar, putchar und mehr habe ich nicht was ich dem
Code anbieten kann.
Die hier sind vermutlich nicht erforderlich und können leer bleiben,
gibt es keine Aequivalente bei mir zu.
Ok, mal schauen wie es sich so durchkompiliert mit dem sdcc.
/*----------------------------------------------------------------------
------------------------------------------------------------------------
-----
* PHYIO: set/reset nodelay
*-----------------------------------------------------------------------
------------------------------------------------------------------------
----
*/
static void
mcurses_phyio_nodelay (uint8_t flag)
{
int fd;
int fl;
fd = fileno (stdin);
if ((fl = fcntl (fd, F_GETFL, 0)) >= 0)
{
if (flag)
{
fl |= O_NDELAY;
}
else
{
fl &= ~O_NDELAY;
}
(void) fcntl (fd, F_SETFL, fl);
mcurses_nodelay = flag;
}
}
/*----------------------------------------------------------------------
------------------------------------------------------------------------
-----
* PHYIO: flush output
*-----------------------------------------------------------------------
------------------------------------------------------------------------
----
*/
static void
mcurses_phyio_flush_output ()
{
fflush (stdout);
}
Christian J. schrieb:> * PHYIO: set/reset nodelay> * PHYIO: flush output
Schau Dir besser die AVR-Version der phyio-Funktionen an und passe diese
dann an. Du hast hier nämlich die Linux-/Unix-Versionen gepostet. Diese
erscheinen für einen Nicht-Unixer erstmal wesentlich komplexer.
mcurses.c ist da folgendermaßen aufgebaut:
1
#ifdef unix // UNIX-/Linux-Version
2
3
*PHYIO:init
4
*PHYIO:done
5
*PHYIO:putc
6
*PHYIO:getc
7
*PHYIO:set/resetnodelay
8
*PHYIO:flushoutput
9
10
#else // AVR-version
11
(Wiederholungderphyio-FunktionenfuerAVR)
12
#endif
13
14
(Restistplattformunabhaengig)
Du solltest das jetzt folgendermaßen erweitern:
1
#ifdef unix // UNIX-/Linux-Version
2
(Unix-phyio-Funktionen)
3
#elif defined (DEIN_Z80_KRITERIUM) // Z80 Version
4
(Z80-phyio-Funktionen)
5
#else // AVR-version
6
(AVR-phyio-Funktionen)
7
#endif
8
(Restistplattformunabhaengig)
Dafür kopierst Du Dir am besten die AVR-phyio-Funktionen und passt diese
an. Sollte Deine Portierung dann erfolgreich sein, kann ich die neue
mcurses-LIB, welche auch den Z80 unterstützt, gerne wieder zum Artikel
als Download beifügen.
Christian J. schrieb:> Weil der Entwicklungsleiter nichts anderes konnte und Angst hatte> von einem Jüngeren "überflügelt" zu werden.
Das ist kein µC-Buden spezifisches Problem und einer der häufigsten
Hintergründe von Mobbing, sogar in Sozialberufen. Die Ursache dafür ist
im ehemals satten Arbeitskräftemarkt zu suchen, nachdem es möglich
wurde. (langjärige) Mitarbeiter nicht mehr weiterzuqualifizieren sondern
durch jüngere scheinbar qualifiziertere Mitarbeiter nach dem Hire & Fire
Prinzip zu ersetzen.
.....
Namaste
Frank M. schrieb:> Die neue Version ist online, siehe MCURSES.
Auch das zip? Da steht noch 2011.....
>>Du solltest das jetzt folgendermaßen erweitern:
Ich habe stur gelöscht :-) Alles weg was zuviel ist.
hallo frank,
ich habe deinen code erstmal beiseite gelegt, da mir der kopf raucht und
ich alles durcheinander werfe. da muss sehr viel geändert werden, da der
Z80 ja eine CPU ist, alles andere ist individuell. Und ich brauche auch
nur eine Sache, nämlich getch. Du holst Zeichen im Interrupt, ich
aktuell noch per Hand.
Trotzdem steige ich noch nicht hinter das Prinzip, habe alles erstmal
bei mir gelöscht und auf wenige Zeilen reduziert um mit diesem minicom
klar zu kommen. gets sendet echos und macht es "richtig" aber getchar
nicht, da muss ich alles per hand machen.
do
{
ch = getchar();
putchar(ch);
} while (ch!=0x0d);
printf("\r\nFertig");
Man sollte annehmen, dass ich dann genau das sehe was ich tippe aber da
fängt es schon an. Backspace löscht keine Zeichen sondern ist wie Cursor
verschieben. Pfeiltasten laufen hoch und runter im Terminal: ok. Up und
Down muss ich eh unterbinden bei einem Einzeilen Editor.
Lese ich Pfeiltaste als hex aus erhalte ich immmer 0x1b 0x51 als Code,
egal welche ich tippe. Wieviel Bytes sind das überhaupt? 2 oder 3? Pos1
und Ende erzeugen "F"'s. Kann aber sein, dass zeichen verschluckt werden
bei mir, printf ist schon sehr zeitintensiv.
Bevor ich da nicht durch die Grundlagen durchsteige unddie
Zeicheneingabe auf einen Interrupt lege in einen Puffer hat es keinen
Zweck da weiter zu machen. Das gibt Murks.
Und jetzt ist Ende... Kopffestplatte ist voll.
Entschuldigt falls das hier falsch sein sollte.
Ist das Board hier geeignet für ein Retro PC
MX98726 + 80186 MACRONIX Demo Board A24/2923
Danke schon mal.
Christian J. schrieb:> ich habe deinen code erstmal beiseite gelegt, da mir der kopf raucht und> ich alles durcheinander werfe.
Ja, merkt man.
> da muss sehr viel geändert werden, da der> Z80 ja eine CPU ist, alles andere ist individuell.
Nein, da muss gar nicht viel geändert werden.
> Und ich brauche auch> nur eine Sache, nämlich getch. Du holst Zeichen im Interrupt, ich> aktuell noch per Hand.
Das spielt überhaupt keine Rolle, wie die Zeichen geholt werden.
Du musst nur die phyio-Funktionen anpassen, mehr nicht. Aber das sagte
ich ja bereits.
Hier eine Minimalversion:
> Trotzdem steige ich noch nicht hinter das Prinzip, habe alles erstmal> bei mir gelöscht und auf wenige Zeilen reduziert um mit diesem minicom> klar zu kommen. gets sendet echos und macht es "richtig" aber getchar> nicht, da muss ich alles per hand machen.
mcurses benutzt für die Plattformunabhängigkeit ein
Mini-Schichtenmodell:
- Unabhängige Funktionen wie getch() und addch() usw.
- Plattformabhängige PHYIO-Funktionen wie getchar(), putchar
Alles einfach rauszuschmeissen, was Du nicht verstehst, ist der komplett
falsche Weg. Offenbar hast Du Probleme, systematisch eine Aufgabe zu
lösen.
>> do> {> ch = getchar();> putchar(ch);> } while (ch!=0x0d);> printf("\r\nFertig");
Genau das macht macht getnstr() - nur auf der mcurses-Ebene und nicht
auf der Low-Level-PHYIO-Ebene. Auf der Low-Level-Ebene bist Du verratzt
und verkauft, wenn man Cursor-Tasten etc. drückt. Das klappt nicht!
> Man sollte annehmen, dass ich dann genau das sehe was ich tippe aber da> fängt es schon an. Backspace löscht keine Zeichen sondern ist wie Cursor> verschieben. Pfeiltasten laufen hoch und runter im Terminal: ok. Up und> Down muss ich eh unterbinden bei einem Einzeilen Editor.
Ist doch klar: Die Sondertasten senden ESCAPE-Sequenzen, die Du nicht
auswertest, sondern einfach in Deinem Buffer abspeicherst. Das klappt
nicht!
Entweder Du machst es richtig oder Du lässt es. Wenn Du alles
rausschmeisst, was Du nicht verstehst, ist das alles zum Scheitern
verurteilt. Also bohre - so wie gestern skizziert - die Struktur auf:
#ifdef unix
#elif defined (DEIN_Z80_KRITERIUM)
#else // AVR
#endif
und knalle da einfach die PHYIO-Routinen, die ich oben aufgeführt habe,
in den Z80-Bereich! Was ist da so schwierig? Ich habe irgendwie das
Gefühl, dass Du mal gerne Hinweise anderer ignorierst und Dich dabei
dann in einer Sackgasse verrennst. Ja, ich kenne den SDCC-Thread.
Dann musst Du oben in mcurses.c noch dort, wo die plattformabhängigen
includes geschehen, noch die Z80-Anpassungen machen:
1
#ifdef unix
2
#include<termio.h>
3
#include<fcntl.h>
4
#define PROGMEM
5
#define PSTR(x) (x)
6
#define pgm_read_byte(s) (*s)
7
#elif defined (DEIN_Z80_KRITERIUM) // NEU
8
#define PROGMEM // NEU
9
#define PSTR(x) (x) // NEU
10
#define pgm_read_byte(s) (*s) // NEU
11
#else
12
#include<avr/io.h>
13
#include<avr/pgmspace.h>
14
#include<avr/interrupt.h>
15
#endif
> Lese ich Pfeiltaste als hex aus erhalte ich immmer 0x1b 0x51 als Code,> egal welche ich tippe. Wieviel Bytes sind das überhaupt? 2 oder 3? Pos1> und Ende erzeugen "F"'s. Kann aber sein, dass zeichen verschluckt werden> bei mir, printf ist schon sehr zeitintensiv.
Google nach "vt100 escape" und Du wirst jede Menge Listen finden, wo die
Tasten erklärt sind. Aber ich glaube nicht, dass Du in der Lage bist,
Dein Problem auf dieser unteren Ebene zu lösen. Deshalb habe ich Dir
mcurses angeboten. Für die Entwicklung eines Monitors musst Du sowieso
auf dem Bildschirm frei positionieren können. Ich rate Dir daher,
sämtliche Benutzer-Interaktionen mit mcurses zu machen - nicht nur die
Kommando-Eingabe.
> Bevor ich da nicht durch die Grundlagen durchsteige unddie> Zeicheneingabe auf einen Interrupt lege in einen Puffer hat es keinen> Zweck da weiter zu machen. Das gibt Murks.
Du musst überhaupt keinen Interrupt einbauen! Ich habe Dir gestern schon
gesagt, dass Du putchar() und getchart() in die Phyio-Funktionen
einbauen musst - mehr nicht! Höre doch einfach mal zu!
Du brauchst die untere Ebene und die Escape-Sequenzen gar nicht zu
kennen, wenn Du mcurses nutzt! Lass den mcurses-Source im Ganzen stehen!
Wirf nichts raus, sondern erweitere den Source! Nur so kann ein
Software-Paket wachsen. Ein Paket zu schnappen und dann rigoros
abzuspecken ("ich brauche nur getch()!") ist der falsche Weg, denn damit
löst sich alles in Luft auf und es bleibt nichts lauffähiges übrig.
Und jetzt am Ende noch 3 Bitten:
- Lies dieses Posting 3 mal
- Lies dieses Posting 3 mal
- Lies dieses Posting 3 mal
Christian J. schrieb:> ich habe deinen code erstmal beiseite gelegt, da mir der kopf raucht und> ich alles durcheinander werfe.
So, ich habs nicht mehr ausgehalten ("das kann doch nicht so schwer
sein!") und habe mir mal den SDCC installiert, die oben aufgeführten
Änderungen eingebaut, noch hier und da eine kleine Änderung/Optimierung
(include-Tausch, Mini-itoa-Ersatz geschrieben, um sprintf-Aufruf
einzusparen) und dann durch den SDCC gejagt.
Die Übersetzung von mcurses.c funktioniert nun. Aufwand meinerseits zur
Code-Anpassung: 10 Minuten.
Ich habe das mcurses-Paket (s. Download im Artikel MCURSES) mit der
neuen Version 2.0.0 hochgeladen. Die Änderungen erkennst Du an
__SDCC_z80 in mcurses.c. Diese Konstante wird automatisch vom SDCC
gesetzt, wenn man mit -mz80 compiliert.
Jetzt brauchst Du nur noch zu testen, am besten mit diesem main.c:
1
#include"mcurses.h"
2
3
intmain()
4
{
5
charbuf[40];
6
7
mvaddstr(9,10,"Bitte eine Zeichenkette eingeben:");
8
mvgetnstr(10,10,buf,40);// Einlesen eines String mit 79 Zeichen + '\0'
9
mvaddstr(11,10,buf);// Ausgabe des Strings eine Zeile darunter
Hi,
ist schon deutlich klarer und ich werde es heut abend auf meine Int
gesteuerte Zeichenausgabe/eingabe anpassen. Gestern war nur ein Punkt wo
nichts mehr ging und wo man besser aufhört und sich nicht in Dinge
verbeisst, die an dem Tag einfach nicht mehr gehen. Dass die Low Level
Ebene nicht ganz einfach ist habe ich auch gemerkt, da ich angefangen
hatte das alles selbst zu schreiben.
Ok..... melde mich erst wieder wenn es klappt.
Christian J. schrieb:> ist schon deutlich klarer
Hast Du auch meinen Beitrag von 10:53 Uhr gelesen? Ich habe mcurses.c
bereits auf SDCC portiert, Du kannst Dir mcurses.zip daher nochmal
runterladen. Viel Spaß!
Es kompiliert auf dem Cubie Truck fehlerfrei durch, grad ausprobiert,
bzw nur die Warnungen wegen der crt0.s, die ich noch anpassen muss, weil
da die .globl definiert werden wollen. 2046 Bytes Code.
Bin noch dran die Verbindung zwischen meinem Empfangspuffer her
zustellen, da ich gestern abend mit der letzten kraft nach 3 Kaffee
nachts um 2 Uhr auf Int umgestellt habe, damit nicht ewig Zeichen
verschwinden.
itoa ist auf dem sdcc verfügbar, allerdings etwas speicherfressend.
Dumme Frage: Das Schlüsselwort "unix" vorne, wo wird das definiert? Vom
system her oder dem GCC? Preprozessor Sachen habe ich bisher wenig
gemacht.
Uart u.a. Init sieht übrigens so aus, das ist bei jedem anders, je
nachdem welche Chipse man nimmt
Christian J. schrieb:> Es kompiliert auf dem Cubie Truck fehlerfrei durch, grad ausprobiert,> bzw nur die Warnungen wegen der crt0.s, die ich noch anpassen muss, weil> da die .globl definiert werden wollen. 2046 Bytes Code.
Prima.
> itoa ist auf dem sdcc verfügbar, allerdings etwas speicherfressend.
Dann lass es so, wie es ist. Da es sich um maximal dreistellige
Dezimalzahlen handelt (für die Cursor-Positionierung), habe ich das ganz
nativ in C in 10 Zeilen gelöst - siehe Funktion mcurses_puti().
> Dumme Frage: Das Schlüsselwort "unix" vorne, wo wird das definiert?
Das wird definiert, wenn man einen C-Code für ein Unix-/Linux-System
compiliert. Da Du für einen Z80 compilierst, ist "unix" NICHT definiert.
Es geht also hier immer um das Zielsystem!
Der SDCC setzt automatisch __SDCC_z80.
Deshalb findest Du in mcurses.c nun vor:
1
#if defined(unix)
2
macheUnix-spezifischenCode
3
#elif defined(__SDCC_z80)
4
macheZ80-spezifischenCode
5
#else // AVR
6
macheAVR-spezifischenCode
7
#endif
Die plattformabhängigen Teile sind also komplett voneinander getrennt.
Die nicht zutreffenden Teile werden NICHT compiliert, sondern komplett
ignoriert.
> Vom system her oder dem GCC?
Der gcc (aber auch jeder andere C-Compiler) setzt das, wenn das
Zielsystem ein Unix ist. Das ist schon seit 1969 so, da gab es noch
keinen gcc.
Wenn das Zielsystem aber ein AVR ist, ist unix NICHT gesetzt. Ebenso
nicht beim SDCC, wenn -mz80 für das Zielsystem angegeben ist.
> Preprozessor Sachen habe ich bisher wenig gemacht.
Hm, eine vom Compiler definierte Konstante abzufragen gehört aber zum
Basis-Wissen. Hast Du mal in SDCC-Manual geschaut? Da wird genau
erklärt, für welches Zielsystem der SDCC was setzt.
> Uart u.a. Init sieht übrigens so aus, das ist bei jedem anders, je> nachdem welche Chipse man nimmt
Okay, du musst das Uart-Init ja nicht in initscr() machen, sondern
kannst das aufrufen, wo und wann Du willst. Aber mindestens vor
initscr(), damit mcurses mit einem vollständig initialisiertem UART
loslegen kann.
Lass Dich knutschen Frank :-) (scherz)
siehe Bild.
Erstmal ohne Interrupts, damit es endlich was zu sehen gab. Für die Ints
werde ich getchar und putchar umschreiben, so dass sie direkt auf den
Buffer gehen und nicht mehr auf die Hardware.
Damit nichts doppelt gemoppelt wird: Deine Ringbuffer sind nur für AVR
bei Verwendung von ISR? Ich habe die Funktion getchar und putchar einige
Male gefunden, die ich ja durch meine eigene überschrieben habe.
>>Hm, eine vom Compiler definierte Konstante abzufragen gehört aber zum>>Basis-Wissen.
Es gab in 17 jahre nie eine Notwendigkeit Code zu schreiben, der für
mehr als das Zielsystem benutzt wurde und niemals veröffentlicht worden
ist. Man weiss nur das was man braucht, nicht das was man nicht benutzt.
Na also, geht doch :-)
Wie schon erwähnt:
Ich würde Dir raten, das komplette Benutzerinterface Deiner Anwendung
über mcurses abzuwickeln, nicht nur die Eingabe eines Kommandos. Damit
hast Du eine Menge Komfort gewonnen. Du kannst dann den Bildschirm
löschen, Deinen Text beliebig positionieren und auch noch mit Attributen
(Bold, Underline, Vorder- und Hintergrund-Farben etc) versehen.
> Damit nichts doppelt gemoppelt wird: Deine Ringbuffer sind nur für AVR> bei Verwendung von ISR?
Ja, die sind nur für AVR. Unter Unix-/Linux laufen die Interrupts
komplett im Betriebssystem selbst, getchar() und putchar() arbeiten
bereits mit Buffern, ohne dass es der Programmierer überhaupt
mitbekommt.
> Ich habe die Funktion getchar und putchar einige> Male gefunden, die ich ja durch meine eigene überschrieben habe.
Du hast also in mcurses.c die putchar() und getchar()-Aufrufe nochmal
ersetzt? Warum? Okay, Du könntest für Deine eigenen IO-Funktionen
natürlich auch noch einen Interrupt-gesteuerten Ringbuffer einbauen.
Aber das ist eine Optimierung, die ich erst machen würde, wenn alle
anderen Probleme glattgebügelt sind. First make it work, then make it
fine ;-)
Das einzige, was für mich jetzt noch für eine vollständige Portierung
auf SDCC (Z80) interessant wäre, ein nicht-blockierendes getchar()
hinzubekommen. Das dafür zuständige flag kann man ja über die
mcurses-Funktion nodelay(flag) setzen. Funktioniert auch für Unix-/Linux
und AVR perfekt. Wenn Du da etwas weisst bzw. einen Tipp hast, würde ich
diesen noch offentstehenden Teil in mcurses ebenso noch für SDCC
umsetzen.
Dann wäre für mich alles komplett und rund.
Frank M. schrieb:> Das einzige, was für mich jetzt noch für eine vollständige Portierung> auf SDCC (Z80) interessant wäre, ein nicht-blockierendes getchar()> hinzubekommen.
Das bin ich schon dran. Aber das ist nicht "portierbar", da jedes Z80
System anders ist, je nachdem welche Chips man benutzt.
Ich nehme den Stromfresser MK3801 Multi I/O Chip mit dem Seltenheitswert
eines Oldtimers, da der 3 in 1 hat, Timer, SIO, GPIO und ncht 3
40-Pinner-Trümmer die Platine zustellen.
Dafür benutze ich den Timer A im Free Running Mode, der so halbwegs auf
100Hz eingestellt ist und nach ca 0,5 das Timeout auslöst und die
getchar Routine darüber informiert wird.
[code]
///////////////////////////////////////////////////////
// Zeicheneingabe von der Uart
// Achtung, kein Timeout!
char getchar()
{
while ((STI_RSR & 0x80) == 0);
return(STI_UDR);
}
wird dann zu:
while ( !(STI_RSR & 0x80) && !(rx_timeout);
das ginge "portabel" nur in dem bei mcurses die Existenz eines
putchar_timeout Flags vorausgesetzt würde.
>>Du hast also in mcurses.c die putchar() und getchar()-Aufrufe nochmal>>ersetzt?
Ich habe in mcurses nicht eine einzige zeile angefasst, gar nichts.
Nein, meine eigene überschreibt die interne putchar. Damit nutzt dein
Modul, da es als letztes kompiliert wird natürlich auch meine Routine.
Die im sdcc sind leer, da der sdcc nicht weiss was gemacht werden soll.
Die Definition der Variablen z80_nodelay kannst Du dann löschen.
Oder Du baust die Abfrage auf mcurses_nodelay in Deine eigene
getchar()-Funktion. mcurses_nodelay ist aber im Moment "versteckt", d.h.
static. Das static müsstest Du dann entfernen, damit Du aus Deinen
eigenen Routinen drauf zugreifen kannst. Ist aber Geschmackssache. Denn
eigentlich sind die PHYIO-Funktionen genau für den Hardware-Teil
gedacht.
Habe ich, klappt immer noch, a die puts und gets ja in den Hardware Teil
gehören ujnd nicht ins Userprog.
Nochmal: Du schlägst also vor, dass ich meine Menüsterung unter Nicht
Verndung von printf oder meinem Speichersparenden printstrng komplett
auf mcurses umstelle? Nur werden dann so Themen wie Scrolling aktut,
denn ein normales Terminal läuft ja nach oben immer weiter. Bisher sehe
ich nur absolute Zeilenadressierung in den Funktionen. (Ein 4 Gewinnt
Spiel wird da allerdings interesannt, da es stehen bleibt und nicht
immer wieder neu erzeugt wird)
Das sieht ja später so aus
menü 1..........
menü 2..........
menü 3..........
menü 4..........
usr> <usereingabe>
Habe nur das hier gefunden:
extern void setscrreg (uint8_t, uint8_t);
// set scrolling region
z80> <Antwort auf Eingabe>
PS: Ich möchte nicht wissen wie jetzt genau das Cursor Verschieben und
das verschieben von text funktioniert, wenn man im Wort weitertippt. Ich
nehme es einfach so hin.
Christian J. schrieb:> Nochmal: Du schlägst also vor, dass ich meine Menüsterung unter Nicht> Verndung von printf oder meinem Speichersparenden printstrng komplett> auf mcurses umstelle?
Ja, wäre doch nur eine logische Konsequenz.
> Nur werden dann so Themen wie Scrolling aktut,> denn ein normales Terminal läuft ja nach oben immer weiter. Bisher sehe> ich nur absolute Zeichenadressierung in den Funktionen.
Ich weiß nicht, wieviel Output Du da machst. Kannst Du den nicht so
portionieren, dass immer eine Seite ausgegeben wird? Wie gesagt, die
Funktionen clear() und clrtobot() existieren :-)
Ausserdem kann mcurses sogenannte Scrolling Regions. Beispiel:
Das Terminal soll nur von den Zeilen 2 bis 22 Scrollen und damit die
Zeilen 1, 23 und 24 "einfrieren". Dann kannst Du oben bzw. unten
Statuszeilen anzeigen (Temperatur, Uhrzeit und was weiß ich), die immer
an derselben Stelle sein sollen.
dafür gibt es die folgenden mcurses-Funktionen, die Du mal im Artikel
näher betrachten und ausprobieren solltest:
- setscrreg() setzt Scrolling-Region
- deleteln() löscht eine Zeile an der aktuellen Position.
Darunter liegende Zeilen innerhalb der Scrolling-Region
rollen damit automatisch hoch!
- insertln() fügt eine Zeile an der aktuellen Position ein.
Darunter liegende Zeilen innerhalb der Scrolling-Region
rollen damit automatisch runter!
- scroll() rollt die komplette Scrolling-Region hoch.
> Das sieht ja später so aus>> menü 1..........> menü 2..........> menü 3..........> menü 4..........> z80> <usereingabe>
Ja, prima, damit kannst Du dafür sorgen, dass das Menü immer an
derselben Stelle erscheint. Das wirkt wesentlich professioneller.
Nach der Eingabe machst Du erstmal einen clear(), wenn die Ausgabe
länger wird. Dann kannst Du oben links innerhalb der Scrolling-Region
anfangen. Wenn Du rollen willst, dann rufst Du scroll() auf.
Spiel mal ein wenig mit den mcurses-Funktionen rum! Es lohnt sich.
P.S.
Vielleicht hast Du es schon gemerkt: mcurses fängt bei 0 bzgl. Spalten
und Zeilen zu zählen. Bei 24 Zeilen kannst Du mit setscrreg(0, 23) die
Scrolling-Region auf den kompletten Bildschirminhalt setzen. Dann rollt
alles wie gewohnt. Bei setscrreg(0, 22) hast Du unten immer eine
Statuszeile, die nicht mitrollt, bei setscrreg(1, 23) ist die
eingefrorene Zeile oben.
Vielleicht willst Du aber auch, dass nur der halbe Bildschirm gerollt
wird? Dann rufe setscrreg(12, 23) auf. Dann hast Du oben 12
feststehende Zeilen fürs Menü etc. und unten rollt die Ausgabe. Du
könntest damit zum Beispiel auch einen einfachen Hex-Editor bauen...
Ok,
ich denke ich habe jetzt ne Menge erstmal auszuprobieren (ohne das
dämliche EPROM Brennen. Sieht ganz witzig aus mit rand x,y Positonen zu
erzeugen und alles vollzuschreiben, kreuz und quer.
Muss erstmal sschauen wie ich minicom beibringe eine feste
Bildschirmgröße zu haben, das Fenster ist ja beliebig scalierbar bisher.
Letzte Frage: Wie hatst du es geschafft dass getnstr (buf, 40); und
andere sowohl eine Position als Paramdeter verstehen als auch ohne
Positionsangabe?
eit: erledigt. mv... mit und ohne. Man lernt immer was Neues dazu...
#define erase() clear()
// clear total screen, same as clear()
#define mvaddch(y,x,c) move((y),(x)), addch((c))
// move cursor, then add character
#define mvaddstr(y,x,s) move((y),(x)), addstr((s))
// move cursor, then add string
#define mvaddstr_P(y,x,s) move((y),(x)), addstr_P((s))
// move cursor, then add string (PROGMEM)
#define mvinsch(y,x,c) move((y),(x)), insch((c))
// move cursor, then insert character
#define mvdelch(y,x) move((y),(x)), delch()
// move cursor, then delete character
#define mvgetnstr(y,x,s,n) move((y),(x)), getnstr(s,n)
// move cursor, then get string
#define getyx(y,x) y = mcurses_cury, x = mcurses_curx
// get cursor coordinates
Christian J. schrieb:> Letzte Frage: Wie hatst du es geschafft dass getnstr (buf, 40); und> andere sowohl eine Position als Paramdeter verstehen als auch ohne> Positionsangabe?
Die Funktion heisst getnstr(char * str, uint8_t maxlen).
Aber es gibt noch ein Makro in mcurses.h:
Es wird also hier erst ein move(), dann getnstr() aufgerufen. Die beiden
Befehle sind durch Komma getrennt statt Semikolon. Das bewirkt, dass der
Compiler beides wie einen (geklammerten) Block betrachtet.
Sonst könnte dies Probleme machen:
if (irgendeine_Bedingung)
mvgetnstr(....);
else
tuewasanderes();
Das else würde der Compiler in den falschen Hals kriegen, wenn oben ein
Semikolon stünde, da hier nix geklammert ist. (Deshalb klammere ich
immer alles, auch wenn es nur ein Statement unter einem if ist).
#define mvgetnstr(y,x,s,n) do { move((y),(x)); getnstr(s,n); } while (0)
> Das else würde der Compiler in den falschen Hals kriegen, wenn oben ein> Semikolon stünde, da hier nix geklammert ist.
Dann passiert das nicht.
> (Deshalb klammere ich> immer alles, auch wenn es nur ein Statement unter einem if ist).
Und die Klammern in diesen Fällen sind wieder reine Geschmacksache.
Ja, ich kenne diese Konstruktion und benutze sie im allgemeinen auch
gern.
Da aber nicht alle Compiler so schlau auf dieser Welt sind wie gcc, wird
daraus manchmal auch im Compiler-Output eine echte do-while-Schleife -
mit dem einzigen Effekt, dass der Code aufgeblasen wird und eine
unnötige Bedingung getestet wird. Kann der SDCC das genauso gut wie der
gcc?
> Dann passiert das nicht.
Das passiert mit dem Komma-Operator auch nicht. Auch hier kannst Du dann
im Code die Klammern gefahrlos weglassen.
> Und die Klammern in diesen Fällen sind wieder reine Geschmacksache.
Eben. Wie gesagt: Der Komma-Operator löst die Aufgabe genauso gut wie
eine geklammerte do-while-Fake-Schleife.
Zusatz:
Der Komma-Operator hat noch einen Vorteil: Man kann im Macro mit
return-Werten arbeiten, z.B.
#define mvgetch(y,x) move(y,x), getch()
Dann kann man schreiben:
int ch;
ch = mvgetch(10, 11);
Mit einer do-while-Schleife wäre das nicht lösbar.
(Man muss dazu anmerken, dass beim Komma-Operator, der Return-Wert immer
derjenige der zuletzt aufgerufenen Funktion ist. Das ist einfach
praktisch :-) )
Frank M. schrieb:> Kann der SDCC das genauso gut wie der> gcc?
Sieht so aus. Hab dein Demo grade in aller Eile durch den Compiler
gejagt. Hier ein Outputschnipsel:
1
;demo.c:138: mvdelch (3,0);
2
; genIpush
3
push de
4
;fetchPairLong
5
;fetchLitPair
6
ld hl,#0x0003
7
push hl
8
; genCall
9
call _move
10
pop af
11
; genCall
12
; peephole 44 eleminated dead pop/push pair.
13
call _delch
14
;demo.c:139: PAUSE (25);
>> Und die Klammern in diesen Fällen sind wieder reine Geschmacksache.>> Eben. Wie gesagt: Der Komma-Operator löst die Aufgabe genauso gut wie> eine geklammerte do-while-Fake-Schleife.
Mit dem Komma im Makro sind sie zwingend, keine Geschmacksache.
Muss jetzt leider dringend weg. Ich melde mich später in deinem
MCURSES-Thread wieder.
Frank M. schrieb:> Da irrst Du gewaltig.
Hast recht, da war ich zu sehr im Zeitdruck. Kommaoperator mag ich an
der Stelle trotzdem nicht. ;)
Frank M. schrieb:> Der Komma-Operator hat noch einen Vorteil: Man kann im Macro mit> return-Werten arbeiten, z.B.>> #define mvgetch(y,x) move(y,x), getch()
Wenns aussieht wie eine Funktion, die einen Wert liefert, sollte es auch
überall so verwendet werden können. Als Parameter einer Funktion gehts
aber schief.
Das Beste wäre 'static inline' statt '#define'. Funktioniert auch mit
sdcc. Allerdings baut er den Funktionskörper der inline-Funktion mit
ein, obwohl die Funktion selbst nicht aufgerufen wird.
Nabend,
dank Franks Mini-Editor und anderer Funktionen sind nun die
Möglichkeiten um ein Vielfaches erweitert. es wird langsam Zeit sich
Gedanken um die Struktur der Software zu machen, uns ob Leo Makedatei
noch ausreicht aber ioch hoffe noch mit einem einzigen Verzeichnis
auszukommen und maximal 5-8 Quelldateien.
Kommen wir zu einem Punkt der "Bedienung" über das Terminal. Es wird
sicher nie ein Linux aber elementare Dinge sollen möglich sein.
Load User program
Execute User program
Memory Hex Dump [Adresse]
Kill User Programm
Reset System
Text Spiele
Hardware Funktion 1
Hardware Funktion 2
Hardware Funktion 3
Basic interpreter?
Safe Funktion (wie auch immer)
Ein normaler Parser zerlegt Kommandos in eine Baumstruktur und ist ein
maechtiges Stück Software. Aktuell hat nur der Befehl dump numerische
Parameter nämlich die Adresse die angezeigt werden soll.
Ich denke es reicht, wenn ich mit strcmp eine Liste abklapper
const command const* [] = {"Befehl1", "Befehl2",....
und die Ergebnisse in
struct parsed {
char command token;
char no_params;
int params[n];
}
packe.
Ein Routine verzweigt dann in die jeweilige Funktion und übergibt die
Struktur bzw ist die eh global. Dort werden dann weitere Ausgaben
erzeugt, zb bei dump ist noch einiges möglich.
Erweiterbar ist das alles nicht sonderlich. String Parameter müssten
gesondert behandelt werden aber ein dump 0000 2000 mit der Ausgabe eines
Hex Editor werde ich noch hinbekommen. In der Ausgabe aber editieren
wird schon schwieriger. Nötig wäre es aber nicht.
Im Kopf gehen da noch Sachen herum, wie ein 64k E2PROM, in welches der
RAM Inhalt gespiegelt werden kann, so dass er er sich beim Kaltstart
wieder reinzieht und ausführt aber Platz habe ich keinen mehr, nur noch
auf der Erweiterungsplatine ginge das. I2C über den 8255 ist eine andere
Sache, müsste aber softwaremaessig gehen, Hi, LO, tri State hat er ja,
leider aber eben nur einen ganzen Port mit gleicher Richtung, Bits
wählweise In oder out geht nicht. Da wäre es wenig Retro-mässig einen
AVR oder PIC an den I/O Bus zu hängen und den das E2PROM bedienen zu
lassen. Aber machbar, schnell genug ist er und der Z80 könnte den PIC
als I/O Device einbinden, eine Speicheradresse als Parmeter übergeben
usw.
Was können denn andere Monitore so alles? Einen Debugger habe ich ja
leider nicht, da ich eh in C programmiere und keinen Single Step habe.
Gruss,
Christian
Christian J. schrieb:> Im Kopf gehen da noch Sachen herum, wie ein 64k E2PROM, in welches der> RAM Inhalt gespiegelt werden kann, so dass er er sich beim Kaltstart> wieder reinzieht und ausführt aber Platz habe ich keinen mehr,
Häng einen Akku an dein SRAM, und ein Gatter, das ohne Hauptspannung
inaktives /CS sicherstellt.
Christian J. schrieb:> Erweiterbar ist das alles nicht sonderlich. String Parameter müssten> gesondert behandelt werden aber ein dump 0000 2000 mit der Ausgabe eines> Hex Editor werde ich noch hinbekommen. In der Ausgabe aber editieren> wird schon schwieriger. Nötig wäre es aber nicht.
Ein Hex-Editor mit mcurses ist nicht sehr schwierig. Wenn Du nichts
dagegen hast, kann ich das gerne übernehmen.
Christian J. schrieb:> I2C über den 8255 ist eine andere> Sache, müsste aber softwaremaessig gehen, Hi, LO, tri State hat er ja,> leider aber eben nur einen ganzen Port mit gleicher Richtung, Bits> wählweise In oder out geht nicht.
Mit der Z80-PIO ginge das.
Aber der STI hat doch auch noch ein paar I/O-Leitungen.
Christian J. schrieb:> Was können denn andere Monitore so alles? Einen Debugger habe ich ja> leider nicht, da ich eh in C programmiere und keinen Single Step habe.
1
### Reset reason(s): External.
2
### Setting I2C clock Frequency to 20000 Hz.
3
4
ATMEGA1281+Z8S180 Stamp Monitor
5
6
### main_loop entered: bootdelay=-1
7
8
### main_loop: bootcmd="pin ${pins}; reset; loadf; go ${startaddr}"
9
=> help
10
!cpe - EEPROM copy
11
!mde - EEPROM dump
12
!mdr - RAM dump
13
? - alias for 'help'
14
base - print or set address offset
15
cmp - memory compare
16
connect - Connect to CPU console i/o
17
cp - memory copy
18
date - get/set/reset date & time
19
defaultenv - set all environment variables to their default values
20
echo - echo args to console
21
go - start application at address 'addr'
22
help - print command description/usage
23
loadf - load srec_cat prepared image from controller flash
24
loop - infinite loop on address range
25
md - memory display
26
mm - memory modify (auto-incrementing address)
27
mstep - execute one M cycle
28
mw - memory write (fill)
29
nm - memory modify (constant address)
30
pin - Set or query pin state
31
printenv - print environment variables
32
reset - Keep CPU in RESET state
33
restart - Perform RESET of the CPU
34
run - run commands in an environment variable
35
saveenv - save environment variables to persistent storage
36
setenv - set environment variables
37
sleep - delay execution for some time
38
=> printenv bootcmd
39
bootcmd=pin ${pins}; reset; loadf; go ${startaddr}
40
=> run bootcmd
41
## CPU now in reset state.
42
Loading Z180 memory...
43
From: 0x00000 to: 0x001B9 ( 442 bytes)
44
From: 0x001C2 to: 0x02D9E (11229 bytes)
45
From: 0x02DAE to: 0x03194 ( 999 bytes)
46
## Starting application at 0x0000 ...
47
=> z80_memfifo_init: 0, 7c320
48
z80_memfifo_init: 1, 7c21d
49
z80_memfifo_init: 2, 7c423
50
z80_memfifo_init: 3, 7c526
51
connect
52
DDT/Z - HD64180 (ROM)
53
> ?
54
DDT/Z180 (ROM) Commands:
55
> @ examine/substitute the displacement register @
56
> A [address] Assemble
57
> B[X] display [or clear] all Breakpoints
58
B breakp [:count] [breakp..] set Breakpoints
59
BX address [address..] clear Breakpoints
60
>>C[N][J] [count] trace over Calls [No list] [Jumps only]
61
C[N][J] W|U expression trace over Calls While|Until ...
62
>>D [startadr] [endadr] Display memory in hex and ascii
63
> G [startadr] [;breakp..] Go [to start] [temporary breakpoints]
64
> H [expression [expression]] compute expressions / show High/max load adr.
Super!
Da kommen ja einige Ideen zusammen, auch wenn es fertige Lösungen wie
CPM oder das neue Unix gibt, wo alles drin ist. Besonders die händische
Ansteuerung der Peripherie und Ports werde ich übernehmen von > ?
DDT/Z180 (ROM) Commands.
@Frank: wieso sollte ich was dagegen haben? Ist doch dein Kind. Nur das
Interface für den dump und setup sollte einfach sein. Normalerweise
kreist man doch mit dem Cursor in einem Hex Zahlen Feld herum, rechts
die Ascii Code, links die Adresse. Und CR übernimmt die Daten dann.
Das User Interface aber hat es schon etwas in sich..... vor allem wenn
es plattform unabhängig sein soll, da ja direkter Zugriff auf die
Hardware erfolgt, die ram Zellen.
So Chris jetzt hast du mich angesteckt ;)
Leider habe ich nicht soviel Zeit wie du, aber dafür hoffe ich einen
Schritt schneller zu starten damit ---->
Beitrag "2* UB8830D was mach ich nur mit Ihnen?"
Namaste
Christian J. schrieb:> @Frank: wieso sollte ich was dagegen haben? Ist doch dein Kind. Nur das> Interface für den dump und setup sollte einfach sein. Normalerweise> kreist man doch mit dem Cursor in einem Hex Zahlen Feld herum, rechts> die Ascii Code, links die Adresse. Und CR übernimmt die Daten dann.
Okay, ich baue einen.
Frank M. schrieb:> Okay, ich baue einen.
Ok. Aber das Interface ...... da muss man mal kurz die Hirnzelle
strapazieren.
Input:
1. Memory Range
2. Darstellungsweise: adress, hex.....hex....., ascii?
3. Darstellungs Format?
indivuielle Physical I/O Routinen: Peek und Poke?
Das Interface sollte abgesetzt sein vom übrigen Code und userfreundlich
sein.
Basic Interpreter: das setzt schon ein Speichermedium voraus. Wo soll
derQuelltext hin? Oder die Tokens? Und solch große Code kann ich auch
nicht mal eben portieren. Das ist aktuell noch ne nummer zu gross für
mich. Habe aber eine Lösung im Web gefunden, wo ein PIC für den ich
alles habe an den I/O Buss dran geschlossen wird. Auf die idee kamen
schon andere.
Winfried J. schrieb:> So Chris jetzt hast du mich angesteckt ;)> Leider habe ich nicht soviel Zeit wie du, aber dafür hoffe ich einen> Schritt schneller zu starten damit ---->> Beitrag "2* UB8830D was mach ich nur mit Ihnen?">> Namaste
Wenn das so weitergeht wir das hier irgendwann ein Projekt wie N8VM,
größer und größer und immer mehr wollen auch haben. Platinen werden
gemacht. Modulares Konzept und erweiterbar. Denn ich erinnere mich an
dde Sätze von Rheinhardt Keil (heute ARM) auf seinem 8085 Buch von 1986:
Wer hat mehr von einem Computer? Der ihn fertig kauft oder der ihn
selbst baut und auch versteht?)
Christian J. schrieb:> Basic Interpreter: das setzt schon ein Speichermedium voraus. Wo soll> derQuelltext hin? Oder die Tokens?
Ins RAM. Ein Interpreter ist kein Compiler. Ob du Tokens verwendest oder
nicht: Quelltext = Programm.
Als persitenten Programmspeicher tut es ein Dataflash, oder eine
SD-Card. Alternativ zu BASIC käme auch FORTH im Frage, da sollte sich
auch was auftreiben lassen.
A. K. schrieb:> Häng einen Akku an dein SRAM, und ein Gatter, das ohne Hauptspannung> inaktives /CS sicherstellt.
Ein Akku auf einem IC draufgeschnallt sieht sch.... aus. Kein Platz
mehr. Nur Knopfzelle unter Platine ginge noch.
>>Alternativ zu BASIC käme auch FORTH im Frage, da sollte sich>>uch was auftreiben lassen.
FORTH? Grausam! Kommt mir nicht ins Haus. Du meintest vielleicht FORTRAN
aber das ist eine Compiler Sprache.
Basic Struktur wäre dann also wie folgt
PC -> Z80 Eingabe Quelltext über ncurses
Z80 legt Quelltext zeilen im RAM ab
RUN Command liest diese duch, interpretiert sie und erzeugt auf Konsole
die Ausgabe.
Leider liesse sich der Quelltext aktuell nicht abspeichern, nur indirekt
über den PC als Aufzeichnung über minicom.
Eines nach dem anderen, erst Speichermedium bauen ode ne echte Floppy
dranhängen, aber dann käme FAT noch hinzu.
Leo C. schrieb:> Christian J. schrieb:>> Nur Knopfzelle unter Platine ginge noch.>> Reicht doch
Knopfzelle = 1.5V, nur die großen 3V. Abkopplung von Betriebsspannung
nötig und außerdem muss der CS Pin auf Low gehalten werden und darf
nicht floaten. Das ginge notfalls mit einem Widerstand gegen Masse.
Christian J. schrieb:> FORTH? Grausam! Kommt mir nicht ins Haus. Du meintest vielleicht FORTRAN> aber das ist eine Compiler Sprache.
Nö, FORTH stimmt schon, den Unterschied kenne ich. War mein Favorit beim
AIX65 (6502). BASIC und PL/65 (ein Compiler in 8KB, der mich zum oben
gezeigten PLZ inspirierte) hatte ich dafür auch, aber FORTH war mein
Favorit.
Christian J. schrieb:> Knopfzelle = 1.5V, nur die großen 3V.
"Gross" ist gut. Die Lithium-Zellen gibts auch in klein und Sockel dafür
auch vertikal. Ausserdem darf ein Akku notfalls ein Kabel dran haben,
die Hauptstromversorgung hast du ja auch nicht mit Trafo und Elko und
allem Gedöns auf der Platine drauf.
Hast aber Glück, das Ram hat eine Data Retension Voltage von 1,5V und
1uA..... das passt noch.... nur nicht oben drauf, absolut kein Platz
mehr nicht mal für einen Widerfstand. Die Kämme machen alles dicht.
A. K. schrieb:> <grins>
Jaaaaaaaaaaaaaaaaaaa......... ich weiss es !!! Und es lassen sich auch
kein Drähte neu ziehen, weil man sie nicht identifizieren kann und schon
gar nicht wieder ausfädeln.
Aber es sieht schön aus, sehr aufgeräumt :-)
Winfried J. schrieb:> http://hc-ddr.hucki.net/wiki/lib/exe/fetch.php/tiny:u883bas.zip>> schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den> solltest du leicht portiern können>> ASM listing liegt bei ;)>> Namaste
Sehr schön.... und ich hätte nicht die geringste Ahnung wie ich das Ding
"anschliessen" soll an das Terminal, wie das Interface aussieht usw. Das
sieht mir wie reassemblert aus. Habe auch sowas, den Microsoft
Interpreter. Gibt es aber schöner in C. Kommt später.....
Christian J. schrieb:> Z80 legt Quelltext zeilen im RAM ab
Aber nicht doch! Schon der selige PET 2001 hat zeilenweise geparst und
nur Tokens im RAM abgelegt.
Winfried J. schrieb:> schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den> solltest du leicht portiern können
Von Z8 auf Z80? Das glaube ich eher nicht.
Es gibt ja auch genug fertige Z80 Basic-Interpreter in allen Größen.
Winfried J. schrieb:> schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den> solltest du leicht portiern können
Nochmal <grins>. Von Z8 auf Z80 macht keinen Spass. Z8 ist die
eleganteste 8-Bit Mikrocontroller-Architektur für
Assembler-Programmierung, der ich begegnet bin, wenn man mit den 256
Bytes Datenadressraum auskommt. eZ8 hat da gezwungenermassen schwer
nachgelassen.
Es zeugt von gutem Geschmack, dass sie "drüben" die Z8 abgekupfert
haben, statt Fairchilds F8.
Konrad S. schrieb:> Christian J. schrieb:>> Z80 legt Quelltext zeilen im RAM ab>> Aber nicht doch! Schon der selige PET 2001 hat zeilenweise geparst und> nur Tokens im RAM abgelegt.
Sagte ich doch und dann wurde es hier wieder rumgedreht. Auch der C64
legte nur Tokens ab und rück interpretierte sie beim Listung wieder.
Christian J. schrieb:> aber dann käme FAT noch hinzu.
Du denkst mal wieder zu kompliziert. Bei dem Weg landest du bei Board V2
und sowas wie CP/M.
Wie hat man damals, als das Zeug neu war, Daten gespeichert? Disketten
waren anfangs 8 Zoll gross, mit Laufwerken gross wie eine Schublade und
mit 220V-Motor (hatte sowas etwas später). Normalmensch mit bescheidenen
Finanzen verwendete einen Kassettenrekorder. Das "Filesystem" hiess
Zählwerk und Zettel.
Ok, soweit Retro würde ich nicht empfehlen ;-). Aber das Prinzip lässt
sich auch mit einem Dataflash nutzen: Du teilst ein 2MB Dataflash in 64
Sektoren zu je 32KB auf und verwendest als "Filename" die Nummer des
Sektors. Toteinfach und in ein paar Zeilen erledigt.
Christian J. schrieb:> Ok. Aber das Interface ...... da muss man mal kurz die Hirnzelle> strapazieren.
Ich habe die erste Version hier mal drangehängt. Das Ding kann noch
keine Werte ändern, aber Du kannst schon mit dem Cursor rumlaufen:
links, rechts, oben, unten. Es wird nach oben/unten gerollt, wenn Du
anschlägst. Dann wird die entsprechende Zeile nachgeladen. Die oberste
Zeile bleibt natürlich stehen; hier werden die Scrolling Regions
genutzt.
> Basic Interpreter: das setzt schon ein Speichermedium voraus. Wo soll> derQuelltext hin? Oder die Tokens? Und solch große Code kann ich auch> nicht mal eben portieren. Das ist aktuell noch ne nummer zu gross für> mich. Habe aber eine Lösung im Web gefunden, wo ein PIC für den ich> alles habe an den I/O Buss dran geschlossen wird. Auf die idee kamen> schon andere.
Zum Basic hatte ich Dir eben im mcurses-Thread
Beitrag "Re: MCURSES - Mini Curses Bibliothek für Mikrocontroller"
schon mal Uwe Bergers Basic-Interpreter ans Herz gelegt. Läuft auf AVR,
XMC2GO und auf STM32F4xxx - und benutzt mcurses für den
Full-Screen-Editor.
Schau da mal rein, ich habe Dir dort bereits ein paar Links zum Stöbern
serviert.
Frank M. schrieb:> Ich habe die erste Version hier mal drangehängt.
Hast Du programmieren mit der Muttermilch aufgesaugt? Oder
sprichst "C" fliessend wie Deutsch? Ist ja irre.....
basic Thrad habe ich gesehen, ist aber Unmengen zu lesen und daher
verschoben auf die Tage.
Christian J. schrieb:> Hast Du programmieren mit der Muttermilch aufgesaugt? Oder> sprichst "C" fliessend wie Deutsch? Ist ja irre.....
Ich "spreche" C seit über 30 Jahren... 1982 damit angefangen ;-)
Für heute mache ich Schluss, morgen noch ein Stündchen, dann ist er
fertig.
> basic Thrad habe ich gesehen, ist aber Unmengen zu lesen und daher> verschoben auf die Tage.
Naja, so ein Basic-Interpreter ist schon eine andere Hausnummer... das
geht nicht ganz so schnell.
Frank M. schrieb:> Ich "spreche" C seit über 30 Jahren... 1982 damit angefangen ;-)> Für heute mache ich Schluss, morgen noch ein Stündchen, dann ist er> fertig.
Ich habe hier was für Dich, nur um den Schwierigkeitsgrad noch etwas zu
erhöhen .... nhur was für echte Junkies, ist ja klar :-)
Leo C. schrieb:> Darf ja nicht wahr sein. Ich glaube, ich muß ein Teil meines Regals in> einen Tresor verfrachten...
Ging mir 2001 bei Philips Semiconductor so als wir liquidiert wurden.
Durften stangenweise ICs mitnehmen, alles was da war. packte also einige
Stangen bzw Tape reels ein und da ja Arbeitslosigkeit bevorstand stellte
ich die bei ebay rein. Bezeichnunga abgeschrieben und gut...... Am Abend
stand das Gebot für eine Spule bei etwas über 1800 Euro :-) Es waren
hochwertigste DAC, damals richtig teuer. Habe mich sehr gefreut als die
dann für über 2000 Euro weg ging die Spulen.
PS. Philipp Krause war sehr fleissig bei der neuesten Version des SDCC
Compiler von gestern. Cubietruck compiliert den Source grad durch, 3
Stunden....
2014-11-07 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de>
* device/lib/_modslonglong.c,
device/lib/_modulonglong.c,
device/lib/Makefile.in,
device/lib/*/Makefile.in,
doc/sdccman.lyx:
Implement % for long long and unsigned long long.
* doc/Makefile.in:
More sensible error behaviour when building documentation.
* src/SDCCval.c,
src/SDCCerr.c:
Only warn about long long constants for large values.
* device/lib/_mullonglong.c:
Fix long long multiplication.
* support/regression/tests/*.c:
Enable some long long regression test that pass now.
2014-11-06 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de>
* src/z80/gen.c:
More efficient assignment of literals to 16-bit globals and statics.
2014-11-06 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de>
* src/z80/gen.c,
support/regression/tests/bug-2306.c:
Fixed bug #2306.
2014-11-06 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de>
* src/z80/gen.c,
support/regression/tests/bug-2304.c:
Fixed bug #2304.
* src/z80/ralloc.c,
support/regression/tests/bug-2305.c:
Fixed bug #2305.
2014-10-29 Philipp Klaus Krause <philipp AT informatik.uni-frankfurt.de>
* support/regression/tests/bug-2254.c:
Regression test for bug #2254.
2014-10-22 Philipp Klaus Krause <pkk AT spth.de>
* src/stm8/gen.c:
Spelling fix inspired by Debian patch 02_fix_spelling.
2014-10-22 Ben Shi <powerstudio1st AT 163.com>
* device/lib/stm8/Makefile.in:
* device/stm8/_modslong.s:
* device/stm8/_divslong.s:
Optimized mod & div of signed long.
A. K. schrieb:> Christian J. schrieb:>> aber dann käme FAT noch hinzu.>> Du denkst mal wieder zu kompliziert. Bei dem Weg landest du bei Board V2> und sowas wie CP/M.>> Wie hat man damals, als das Zeug neu war, Daten gespeichert? Disketten> waren anfangs 8 Zoll gross, mit Laufwerken gross wie eine Schublade und> mit 220V-Motor (hatte sowas etwas später). Normalmensch mit bescheidenen> Finanzen verwendete einen Kassettenrekorder. Das "Filesystem" hiess> Zählwerk und Zettel.>> Ok, soweit Retro würde ich nicht empfehlen ;-). Aber das Prinzip lässt> sich auch mit einem Dataflash nutzen: Du teilst ein 2MB Dataflash in 64> Sektoren zu je 32KB auf und verwendest als "Filename" die Nummer des> Sektors. Toteinfach und in ein paar Zeilen erledigt.
Ja, aber ein Kassetteninterface wäre "Retro" :-)
Sowas geht heute aber auch mit einem MP3 Bläher...
Aber ich würde statt Dataflash eine Micro-SD Karte empfeheln, die kann
man auf dem PC ggf. "von außen" laden/sichern/ändern.
Gruß,
Holm
PS: Retro: Ich habe gestern meinen BK0010-01 hervorgekramt und einen
Philips Monitor angeschlossen. Der Text nach dem Einschalten ist rot
und ich habe keine Kabel vertauscht. Das ist ein russischer Homecomputer
mit PDP11-CPU. Heute kommt der Kassettenrecorder dran, es gibt eine
Python Software die die Binärfiles nach WAV umdreht, damit kann ich die
Spiele laden. ..Für Sohnemann als Daddelmaschine..schaunmermal..
Gruß,
Holm
A. K. schrieb:> Winfried J. schrieb:>> schau dir mal den Tinibasic interpreter an der stammt aus dem UB8830 den>> solltest du leicht portiern können>> Nochmal <grins>. Von Z8 auf Z80 macht keinen Spass. Z8 ist die> eleganteste 8-Bit Mikrocontroller-Architektur für> Assembler-Programmierung, der ich begegnet bin, wenn man mit den 256> Bytes Datenadressraum auskommt. eZ8 hat da gezwungenermassen schwer> nachgelassen.>> Es zeugt von gutem Geschmack, dass sie "drüben" die Z8 abgekupfert> haben, statt Fairchilds F8.
"Die" haben alle Z abgekupfert. Z80,Z8,Z8000. Ich habe hier auch ein
Unix (Wega) mit 4 Mhz Z8000.
Gruß,
Holm
Holm Tiffe schrieb:> Aber ich würde statt Dataflash eine Micro-SD Karte empfeheln, die kann> man auf dem PC ggf. "von außen" laden/sichern/ändern.
Oder das, am Interface ändert das wenig. Ich hatte eher die Organisation
gemeint. Ein relativ komplexes Filesystem wie FAT ist im Grunde völlig
unnötig. Er wird das System wohl kaum intensiv fileorientiert betreiben,
wird den Compiler nicht auf die Z80 verlagern (so wars bei Retro in
echt) sondern braucht den Platz nur für ein paar Programm-Images.
Holm Tiffe schrieb:> Ja, aber ein Kassetteninterface wäre "Retro" :-)> Sowas geht heute aber auch mit einem MP3 Bläher...
Ja, das wärs, analog mit FSK via MP3 Player auf µSD. ;-)
Holm Tiffe schrieb:> ..Für Sohnemann als Daddelmaschine..schaunmermal..
Ähm.... glaube meiner würde auswandern...... unter XBOX One mit Headset
und Gamer Account bei GTA geht da nix mehr....
A. K. schrieb:> Oder das, am Interface ändert das wenig. Ich hatte eher die Organisation> gemeint. Ein relativ komplexes Filesystem wie FAT ist im Grunde völlig> unnötig.
Ich habe die Chan Fat erfolgreich auf einem LPC2368 ARM7 zum Laufen
gekriegt. Nur die PHY dazu aus dem Netz besorgt und eingebunden. Einen
Block Treiber haabe ich 2007 mal für PIC mit CCS geschrieben, einfach
nur Blocks ansprechen als Filenummern.
Außerdem gibts das fertig bei Arduino als Lib für die SPI. Plug & play.
Nur die SPI anpassen, Header inkludieren und feddich. Das wäre es also
nicht. Passt allerdings kaum mehr in 8kb EPROM rein, sidn deutlich mehr
als 32KB, dei FAT des Arduino.
Ixh kann nur noch eine zweite Euro karte nehmen und den Rechner auf der
anderen Seite weiter bauen, die beiden über Drahtstege oder Kleber etc
miteinander verbinden. habe leider nicht dran gedacht mehr Platz zu
beschaffen, dachte das bleibt bei einem Minimal System.
Bzw sind wir dann schon bei V2 und einer Messerleiste für den Rechner,
einem Rückwandbus, vielleicht schon bei einem DMA Controller... und jede
Menge Zeit zu haben das zu machen ;-(
Und bevor ich mich schon weit in die Zukunft vergallopiere werde ich
erstmal den Ringpuffer fertig machen, den ich für die Uart geschrieben
habe. Der muss noch gestestet werden, da ich den Fall eines Überlaufes
auch abfangen muss und schauen, ob kein Byte verschwindet am Array Ende,
kennt das ja mit > und >= und dass da schonmal Fehler passieren.
1
uint8_t rx_buffer[RX_BUF_LAST+1]; // Buffer für Zeichenempfang
2
uint8_t rx_rd_ptr = 0; // Read Pointer, nur durch Hauptprogramm lesen
3
uint8_t rx_wr_ptr = 0; // Write Pointer, nur durch Interrupt schreiben
4
5
6
uint8_t rx_buf_full = FALSE; // Es sind Zeichen da
@Frank M:
Als C Spezi ...... mir haut ndie Verwendung von sprintf(buf.. locker 6
kb weg und ich habe nur 8. Aber wenn ich was Gescheites ausgeben will
mti Variablen brauche ich das natürlich. Float muss nicht sein aber
%s,%d,%x schon.
Entweder ich rupfe die Adressleitungen wieder auseinander und hole mir
16KB ROM und nur 48kb RAM oder ich finde eine Lösung Gemischte Strings
preiswerter auszugeben als mit sprintf.
Die mcurses erfordert ja, dass ich auf printf verzichte und stattdessen
sprintf(buf, <Stringausdruck>)
add(<stringbuffer>)
benutze.
Idee?
Christian J. schrieb:> Als C Spezi ...... mir haut ndie Verwendung von sprintf(buf.. locker 6> kb weg und ich habe nur 8.
Und ohne (s)printf kannst du nicht leben... Obacht, auch 64kB reichen
nicht ewig, wenn du in dem Schema weiter denkst und allein für sprintf
fast sowiel Platz brauchst wie Rockwell für einen kompletten Compiler.
Christian J. schrieb:> Holm Tiffe schrieb:>> ..Für Sohnemann als Daddelmaschine..schaunmermal..>> Ähm.... glaube meiner würde auswandern...... unter XBOX One mit Headset> und Gamer Account bei GTA geht da nix mehr....
Sowas gibts in meinem Haushalt nicht.
Computer,Elektronik,Basteln ja. Bei ständig Glotze werde ich ätzend und
einen Gameboy habe ich schon mal höchstpersönlich zerlatscht da die von
Nachwuchs gesetzten Prioritäten justiert werden mußten.
Seit Jahrzehnten repariere ich elektronischen Krempel, die Aktion ging
mir total gegen den Strich, aber sie hat wie gewünscht gewirkt.
Deswegen werfe ich dem Kurzen auch speziell so olle Computer vor, da
kann man auch mal ein Relais anschließen und was steuern. o.ä...
Das ist aber noch Zukunft.
Wenn Deiner auswandern will wegen nicht möglicher Daddelei hast Du
erzieherisch was versaut.
@Christian:
Komm,komm.. diesen Ringpuffer schaffst Du auch in Assembler,
das ist eigentlich Pillepalle auf einem Z80. Da die Sache Deiner Meinung
nach zeitkritisch ist, ist das eine gute Gelegenheit mal 3 ASM Befehle
des Z80 zusammenzurühren. Hier gibts genug Leute die Dir dabei helfen.
Gruß,
Holm
Tjaaaaa..... aber wenn sprintf einmal drin ist sind alle weitere Aufrufe
eben nur Calls.
und da fange ich grad an meine schöne Kämme zu hassen, denn um auf 16KB
aufzubohren muss ich umverdrahten.
A13 | A14 | A15 => CS für 0x0000 - 0x1fff ROM, darüber RAM
für 0x0000 - 0x2fff ROM wäre das
A14 | A15
also A13 abknipsen, Pin auf "1" legen, dazu am EPROM 1 Adressleitung
mehr anschliessen. Am RAM bleibt alles wie gehabt, liegt ja eh unter dem
EPROm. Leider kann ich dann auch die schönen 8KB EEPROM wegwerfen, die
ich bestellt hatte um das Löschen zu vermeiden.
>einen Gameboy habe ich schon mal höchstpersönlich zerlatscht da die von>Nachwuchs gesetzten Prioritäten justiert werden mußten.
Ähmm..... Demokratie? DDR Erziehung? :-)
Ja, Ringbuffer in Asm ist recht überschaubar und eine gute Übung. leider
nur kann ich Asm nicht debuggen, habe nur inline Assembler und wenn da
Fehler drin sind endet das in Ausprobieren, weil eben einen printf
dazwischen geht leider nicht.
Holm Tiffe schrieb:> Komm,komm.. diesen Ringpuffer schaffst Du auch in Assembler,> das ist eigentlich Pillepalle auf einem Z80. Da die Sache Deiner Meinung> nach zeitkritisch ist, ist das eine gute Gelegenheit mal 3 ASM Befehle> des Z80 zusammenzurühren. Hier gibts genug Leute die Dir dabei helfen.
Und wenn er auch dazu keine Lust hat, dann nimmt er eben meinen oben
schon geposteten Code für Z80-SIO, mit Puffer und Hard- und
Software-Handshake, und transponiert ihn auf STI. ;-)
Christian J. schrieb:> Tjaaaaa..... aber wenn sprintf einmal drin ist sind alle weitere Aufrufe> eben nur Calls.
Wie hast du eigentlich in Pascal ohne printf programmiert? ;-)
Ob das mal lohnt..... das ist der komplette Asm der INT Routine,
Leseroutine ist unkritisch, hauptsache die STI ballert die anrollenden
Truppen der Zeichen Kollonnen ins Quartier hinein.
PS: Ausserdem wirkt ein printf in 6kB ziemlich aufgeblasen. Ok, Z80 ist
kein AVR, aber Leute haben schon Mega8 mit printf programmiert und der
hat nur 8KB ROM insgesamt. Das kann man reduzieren, indem nicht zwingend
nötige Formatvariationen rausfliegen.
Christian J. schrieb:> leider nur kann ich Asm nicht debuggen,
Ach? Dabei hat dein Board meiner vagen Erinnerung nach einen
wunderhübschen Debug-Port mit LED-Anzeige drauf. Wie geschaffen fürs
lowlevel-debugging in Assembler.
A.K:
In der 51er SDCC Variante gibt es printf light, ohne Float. In der Z80
habe ich die aber nicht gefunden. Float hat die aber auch nicht sondern
spuckt nur <NOFLOAT> aus. printd verbraucht 3,5 kb, sprintf fast 6KB.
A. K. schrieb:> Ach? Dabei hat dein Board meiner vagen Erinnerung nach einen> wunderhübschen Debug-Port mit LED-Anzeige drauf. Wie geschaffen fürs> lowlevel-debugging in Assembler.
Holm,. wie oft wollen wir die Kartoffel jetzt noch umdrehen? HALT hat
eine LED dran, NMI liegt auf einenm Taster. NMI kann man auch wonaders
anschliesse, weiss ich. Aber mit Fädelkämmen ist da eine Grenze, nämlich
das ist ein write only Board, von modify-read ist da keine Rede mehr.
Einmal verdrahtet ist Ende im Gelände. Ich werde heute nachdem
Spaziergang im schönen Herbstwald noch auf 16KB ROM umverdrahten und
dann soll es gut sein. Ohne sprintf geht es nicht.
und wenn ich hier nahc links schaue, da liegt ein ARM7 Board, 512 KLB
Flash, 60KB RAM, über 100 IO Pins, 3 Uarts, 5 GPIOs, 3 SPIs, 10 Timer
usw. Wieso nehme ich das nicht? :-)
A. K. schrieb:> Hast du eigentlich jemals was selber programmiert? Also so richtig.
Ja, sogar viele tausend Zeilen pro Projekt (VB und C#) aber wenn es geht
nehme ich fertige Sachen ...
Christian J. schrieb:> Holm,. wie oft wollen wir die Kartoffel jetzt noch umdrehen?
Ein Holm ist für mich ein Flugzeugteil. ;-)
Nix NMI, HALT etc. Deine LED-Anzeige ist wie printf, nur mit weniger
Platz drauf. Wenn ich auf AVRs debugge, dann höchst selten per JTAG,
meistens ohne. Der STK500 hat 8 LEDs drauf, so macht man Debugging.
A. K. schrieb:> Der STK500 hat 8 LEDs drauf, so macht man Debugging.
AK, für mich war Debugging bisher dass ein gelber Balken im Source Code
herum läuft, dass ich links hardware Break Points gesetzt habe, rote
pfeile da stehen und Fenster wo ich eine Watchliste habe, die ich mir
selbst aussuchen kann. Ebenso ein Stack Fenster, einen laufzeit Analyser
usw. Du weisst wie eine Keil IDE aussieht für ARM? Oder Rowley IDE mit
JTAG Interface? Das ist wei Mercedes fahren, statt Fiat panda.
Und davon muss man erstmal runter kommen.....
Christian J. schrieb:Entwicklungsumgebung
> AK, für mich war Debugging bisher dass ein gelber Balken im Source Code> herum läuft, dass ich links hardware Break Points gesetzt habe,
Ist mir schon klar. Hoffnungslos verwöhnt. :-)
Bloss ist es ziemlich verwegen, sich an ein Retro-Projekt zu setzen und
den gleichen Luxus vorauszusetzen. Wenn du Z80 Retro programmieren
willst, dann solltest du nicht erwarten, eine Developer Studio mit allem
Gedöns vorzufinden. Sondern eben Retro.
Und dabei bist du immer noch viel besser dran als jene, die Retro
programmierten als das noch Hightech war. Du hast nämlich einen PC
daneben, mit Compiler, Editor usw. Hatte man damals nicht.
> Oder Rowley IDE mit JTAG Interface?
Weiss ich, hab ich, mache ich. Aber ich kann auch ohne.
Christian J. schrieb:> Ähmm..... Demokratie? DDR Erziehung? :-)
Nö, just "old style".
Wenn Hausaufgaben nicht mehr erledigt werden und die Zensuren auf
dreiviertel 12 hängen gibt es keine Demokratie mehr, basta.
Ich halte es da bezüglich Demokratie (die wir eh nicht haben, wir haben
eine Korruption als Gesellschaftsform) wie Volker Pispers.
>> Ja, Ringbuffer in Asm ist recht überschaubar und eine gute Übung. leider> nur kann ich Asm nicht debuggen, habe nur inline Assembler und wenn da> Fehler drin sind endet das in Ausprobieren, weil eben einen printf> dazwischen geht leider nicht.
Mach nix.
Wieviele Timer Kanäle hat eigentlich so eine STI?
bei einem CTC konnte man z.B. den Kanal3, der eh keinen Ausgang hat,so
programmieren, dass er nach jedem Befehl einen Interrupt auslöst. Damit
läßt sich Software-Schrittbetrieb bewerkstelligen. Ein oller DDR
Computer, der MC80.2x hatte ein Zeilenassembler-Disassembler-Testsystem,
das beste was ich kenne um Z80 Code zu debuggen...
Ich habe die Disassemblierten und kommtentierten Assembler Quellen dafür
von Lochstreifen gerettet. Kannste haben wenn Du willst.
Gruß,
Holm
A. K. schrieb:> Und dabei bist du immer noch viel besser dran als jene, die Retro> programmierten als das noch Hightech war. Du hast nämlich einen PC> daneben, mit Compiler, Editor usw. Hatte man damals nicht.>>> Oder Rowley IDE mit JTAG Interface?>> Weiss ich, hab ich, mache ich. Aber ich kann auch ohne.
Hier gibts auch printf mit 1.2kb für 8 Bitter
http://www.sparetimelabs.com/tinyprintf/tinyprintf.php
Und wie haben die damals entwickelt? Natürlich an einem PC bzw CPM oder
was auch immer? Ich weiss doch noch wie das n der Schule war, allerdings
auch 1984 war es da schon. Wie wurden denn Spiel für den C64 gemacht?
Doch nicht auf dem C64 selbst sondern auf einer größeren Maschine.
Es gab WEerkzeuge, jede Menge aber die habe ich nicht und wenn könnte
ich damit nicht umgehen.
A. K. schrieb:> Holm Tiffe schrieb:>> Wieviele Timer Kanäle hat eigentlich so eine STI?>> Einer geht weg für die Baudrate, bleiben drei.
Und wenn man Reload = 1 setzt wird bei jedem Takt ein Interrupt
ausgelöst, da der CTC am Takt dran hängt. Da ein Int aber nur ausgelöst
wird, wenn ein Bfehl abgearbeitet wurde kann man damit Einzelschritt
machen.
Das mit dem Lochkartenleser ist cool, das hätte was. Rrrrr....ratter....
oder beseht da doch die Gefahr in die Steinzeit zu kommen? Haben damals
als Kind mit Vater Streifen gespielt, der bracht Lochband immer mit vom
Telex.
Für Holm:
https://www.youtube.com/watch?v=xqlY0QLmVtwhttps://www.youtube.com/watch?v=EapLXvQ4pt8
Christian J. schrieb:> Und wie haben die damals entwickelt?
Kommt drauf an wer "die" waren. Die wirklich professionellen Entwickler
in den 70ern hatte manchmal In-Circuit-Emulatoren. Und Maschinen der
PDP-11 Klasse als Entwicklungssysteme für Mikrocomputer, klar. Mit in
FORTRAN programmiertem Crossassembler und so. Aber das war insgesamt
gesehen eine winzige Minderheit. Die vielen Bastler programmierten
barebone-mässig.
Anders als Daddler heute hatte man selber in 70ern nicht fertig
programmierte Spiele gekauft, sondern selber an den Kisten rumgebastelt
und programmiert. Und hatte eben keinen Minicomputer daneben, sondern
genau das was als "Computer" da war, nicht mehr.
Und das war in meinem Fall ein AIM65 mit 4KB RAM, einer einzeiligen
Anzeige aus 20 alphanumerischen LEDs und einem 20-stelligen
Thermodrucker à la Registrierkasse. Und immerhin einer kompletten
Tastatur. Nix Bildschirm. Massenspeicher war Muttis Kassettenrecorder.
Und so konnte man wirklich Programme schreiben.
Darauf baute man dann auf und erweiterte. Echten Drucker dranhängen.
Floppy-Controller-Karte bauen und dranhängen, mit besagtem 8-Zoll
Laufwerk. Filesystem dafür bauen (in FORTH). Bildschirmkarte besorgen
(die war ein Bausatz) und dranhängen. Und bis der Bildschirm
funktioniert programmiert man eben mit besagtem 20-stelligen
LED-Display.
> Es gab WEerkzeuge, jede Menge aber die habe ich nicht und wenn könnte> ich damit nicht umgehen.
Die hatte auch sonst kaum einer.
Ok..... da die Werkzeuge heute aber wensentlich besser sind hat sich die
Entwicklung auch mit exponentuieller Geschwindigkeit
A. K. schrieb:> Die hatte auch sonst kaum einer.
Ich habe damals für den C64 ein Speeddos implementiert und eine
Parallelleitung an die 1541 gelötet. Dazu musste auch für den C64 was
geschrieben werden. In 6502 Assembler, wie vieles damals. Da der
Schaltplan und der ROM Coder der 1541 offen waren bzw irgendwo her kamen
ging das. Da war ich 18.
Christian J. schrieb:> Ok..... da die Werkzeuge heute aber wensentlich besser sind
Ok, der Compiler ist auf dem PC. Aber der in den letzten 10 Jahren sehr
beliebte ATmega8 hat kein JTAG. Debugging, so wie du dir das vorstellst,
ist mit diesem Teil technisch ummöglich.
A. K. schrieb:> Und diese Techniken hast du mittlerweile vollständig vergessen?
Ja, vieles ist "weg". Schade aber im Hirn ist nur Platz für 100%. Kommt
was dazu muss einiges vergessen werden. Und 30% sind bestimmt derzeit
mit Normung im Bereich der Maschinenrichtlinie ausgefüllt. Meinem Beruf
eben.
Mein C64, der meine Eltern 1200 DM gekostet hatte landete wegen dem
idiotischen Hausmeister auf dem Sperrmüll und war sofort weg, genau wie
vielen Disketten Wannen. Allerdings habe ich den auch nie wirklich
vermisst und die restlichen Disketten sind leider nicht mehr lesbar mit
dem vielen Asm Code und UCSD Pascal war es auch dafür gab. Habe es vor
3-4 Jahren mal ausprobiert bei einem Bekannten, Bad Blocks überall.
A. K. schrieb:> Ok, der Compiler ist auf dem PC. Aber der in den letzten 10 Jahren sehr> beliebte ATmega8 hat kein JTAG. Debugging, so wie du dir das vorstellst,> ist mit diesem Teil technisch ummöglich.
Häh? das ging schon 1997 mit einem PIC und der MPLAB IDE. Da wurden
einfach Software Breakpoints gesetzt, die einen Int aufriefen. Mit dem
teuren Hardware Debugger sogar HW breakpoints. Luxus. Arduino ist da
Mist gegen, der hat nichts.
Christian J. schrieb:> Häh? das ging schon 1997 mit einem PIC und der MPLAB IDE.
Mit dem ATmega32 und JTAG-Adapter auch. Aber eben nicht mit dem ATmega8.
Der funktioniert ziemlich exakt so wie dein Board. Mehr als einen
Bootloader (d.h. Atmels Programmierschnittstelle) gibts nicht.
Glaube ohne JTAG und einem "Wiggler" könnte ich heute gar nicht mehr
arbeiten... das war die Erlösung als dass Ende der 90iger aufkam und zum
Standard wurde, endlich In-Target programmieren und testen zu können.
Bei PIC wurden damals Spezial Asics gebaut, die einen PIC Core
enthielten aber eben auch Debug Strukturen. Habe einige von den Probes
gehimmelt damals. Glaube 2500 DM das Hauptgerät und jede Probe so um die
500 DM :-)
Ok. bis später mal.
Christian J. schrieb:> Als C Spezi ...... mir haut ndie Verwendung von sprintf(buf.. locker 6> kb weg und ich habe nur 8.
Vergiss sprintf(). Du hast einen Z80 - mehr nicht.
Aber wenn ich was Gescheites ausgeben will
> mti Variablen brauche ich das natürlich. Float muss nicht sein aber> %s,%d,%x schon.
Der Hex-Editor gibt doch auch Hex-Zahlen aus: Siehe Funktion itoxx().
Das reicht. Integer-Zahlen gehen auch: Schau Dir mcurses_puti() an.
Okay, das gibt nur 3-stellige Integers aus (Das reicht hier), lässt sich
aber auch auf 5-stellige Zahlen (max. 65535 = 0xFFFF) leicht erweitern.
Die 3-stellige Ausgabe ist "loop-unrolled", lässt sich aber leicht
wieder zu einer Schleife umbauen, die X Stellen ausgeben kann.
> Entweder ich rupfe die Adressleitungen wieder auseinander und hole mir> 16KB ROM und nur 48kb RAM oder ich finde eine Lösung Gemischte Strings> preiswerter auszugeben als mit sprintf.
Unsinn. Du solltest Dir lieber einen Bootloader für Deinen Z80 stricken,
damit er er Programme (Anwendungen) ins RAM laden kann.
> Die mcurses erfordert ja, dass ich auf printf verzichte und stattdessen>> sprintf(buf, <Stringausdruck>)
sprintf() ist viel zu fett! Für %d und %x reicht obiges, das sind ein
paar hundert Bytes.
A. K. schrieb:> Holm Tiffe schrieb:>> Ja, aber ein Kassetteninterface wäre "Retro" :-)>> Sowas geht heute aber auch mit einem MP3 Bläher...>> Ja, das wärs, analog mit FSK via MP3 Player auf µSD. ;-)
MP3 ist wegen der verlustbehafteten Kompression problematisch. Aber
Christian könnte ja SOUNDRX vom ATmega auf den Z80 portieren. Dann
kann er den Z80 mit Daten über die Soundkarte füttern - durch Abspielen
von WAV-Dateien. Ein PC-Programm, welches Daten in WAV-Dateien
überführt, ist beim SOUNDRX-Paket dabei.
Frank M. schrieb:> Unsinn. Du solltest Dir lieber einen Bootloader für Deinen Z80 stricken,> damit er er Programme (Anwendungen) ins RAM laden kann.
Hat er doch schon, ich spiele über die uart die Soft ein, Reset startet
die auch wieder..... Strom weg = Programm weg. Oder ick packe einen
meiner Modellflug Lipo Akkus davor und der übernimmt dann (kurzzeitig).
Intel Hex Decoder ist in Arbeit, weil meine Lösung etwas "unschön ist",
ich muss die Dateilänge per echo und stat -C.... File dem Z80 mitteilen.
Frank M. schrieb:>> Ja, das wärs, analog mit FSK via MP3 Player auf µSD. ;-)>> MP3 ist wegen der verlustbehafteten Kompression problematisch.
Bei simplem FSK auch? Es geht in diesem Kontext ja nicht um QAM64.
Aber mir ging es eher um die Absurdität des Umwegs über Töne, um dann
doch wieder auf dem digitalen Medium SD-Karte zu speichern.
An meinem 8085 damals habe ich 2 Tongeneratoren angebaut, 1,2 und 2,4khz
mit NE555 für 0 und 1, die gingen auf einen Kassettenrekorder. Direktory
war der Zaehlerstand. Geht aber auch so derzeit, der Upload meine ich.
Christian J. schrieb:> A. K. schrieb:>> Holm Tiffe schrieb:>>> Wieviele Timer Kanäle hat eigentlich so eine STI?>>>> Einer geht weg für die Baudrate, bleiben drei.>> Und wenn man Reload = 1 setzt wird bei jedem Takt ein Interrupt> ausgelöst, da der CTC am Takt dran hängt. Da ein Int aber nur ausgelöst> wird, wenn ein Bfehl abgearbeitet wurde kann man damit Einzelschritt> machen.>> Das mit dem Lochkartenleser ist cool, das hätte was. Rrrrr....ratter....> oder beseht da doch die Gefahr in die Steinzeit zu kommen? Haben damals> als Kind mit Vater Streifen gespielt, der bracht Lochband immer mit vom> Telex.>> Für Holm:>>> https://www.youtube.com/watch?v=xqlY0QLmVtw>> https://www.youtube.com/watch?v=EapLXvQ4pt8
Ähh.. hinter mir auf dem Fußboden, mitten im Sediment steht ein
Lochstreifenleser. Der Stanzer steht im Lager. Meinst Du das Du Holz in
den Wald tragen mußt?
Ich sagte "Ich habe das von Lochstreifen gerettet", das heißt nicht, das
ich damit Jemand anderen belästigt hätte :-) Da hängt ne Platine mit
Atmega16 am Leser..
Ich habe auch einen A5120, der steht allerdings im Lager. Hier zu Hause
habe ich einen K8924 der einen zum A5120 äquivalenten Inhalt hat, man
kommt aber vor vorne an die Karten ran weshalb das Ding besser zum
Basteln ist... nix Neues im Osten also :-)
Gruß,
Holm
Nun Holm,
es gibt sicher nichts was Du nicht hast :-) Und solltest du mal ableben
müssen wir dein Hirn konservieren damit das alles nicht verloren geht.
Ich habe auchn noch sowas hier wie auf dem Bild, ein Teac Laufwerk für
Musik. Und noch 3 Bänder dafür. gab mal ne Zeit um 2000 herum, da wolte
ich unbedingt einen Tape Streamer im Wandformat haben, um darin eine
Hife Anlage unter zu bringen aber leider keinen bekommen, wurden wohl
alle entsorgt damals. Und die Nasa rennt sich die Hacken danach ab, da
die Daten der Mondlandung auch so gesichert wurden und nicht mehr lesbar
sind heute.
Vielleicht hast du ja sowas "auf Lager"+
sehe ich da einen Nakamichi RX-505 im Hintergrund :-)
Die 9spur-Computerbänder waren 1/2 Zoll breit. Müsstest Du also der
Länge nach halbieren, damit sie auf die Teac passen. 9spur-Maschinen
gibt es regelmäßig auf ebay, und bei d.a.f.c wechselt auch ab und zu mal
eine den Besitzer.
Ich habe ein iDigital TSZ70 und ein CM5300.01 aus Bulgarien an 9 Track
Tapes
für Daten. Dazu gesellen sich die Unterschiedlichsten Streamer wobei ich
ein Ultrium 2 aktuell zur Sicherung benutze.
Ein Grundig TS945, ein Tesla B115 (braucht neue Riemen, ist gerade erst
aufgelaufen), einen Jupiter 204, ein BG20 Smaragd und ein BG19 habe ich
an Audiobandgeräten, Kassettenzeuch nix Besonderes DDR Kram und
irgendwas von Sony.
Deine TEAC ist nett aber das hier wäre mein Traum:
http://latemag.com/panasonic-design-museum
Gruß,
Holm
Holm Tiffe schrieb:> Deine TEAC ist nett aber das hier wäre mein Traum:>> http://latemag.com/panasonic-design-museum
Weisst du was diese Dinger kosten? Schon damals? Das war High End, das
Beste vom Besten? Revox war da Marktführer drin. Das Bild ist aus dem
Netz, den Teac habe ich damals günstig bekommen, 250 Euro nur. Ich finde
es stilechter wenn sich da was dreht.
Hast Du mal Bilder von Deinen Streamern? Kaputt ist egal! Sollen nur gut
aussehen :-)
Gruss,
Christian
Weiter gehts mit der Extension Platine. Mit einem DIY Busadapter mangels
Platz für Messerleiste etc.
Geplante HW da drauf: 2 Stück 7-Segment Leisten a 8 Digits mit Maxim
Interface Controller (Libs schon da, daher easy), einige LEDs noch dazu,
1 Timer 8254 (Uhrenn kann man nie genug haben), einer Taktquelle für
eine Uhr, vieleicht auch ne RTC dazu, und vor allem eine Art latenten
Datenspeicher, vermutlich einen AVR oder PIC mit 64k I2C EPROM dran oder
eine Compact Flash karte. Entwder am I/O Bus selbst oder an einer GPIO.
Das muss ich mal sehen...
Christian J. schrieb:> Hat er doch schon, ich spiele über die uart die Soft ein, Reset startet> die auch wieder..... Strom weg = Programm weg.
Aha. Ich dachte, Du müsstest immer noch jedes mal ein EPROM brennen ;-)
Der Full-Screen-Hex-Editor ist übrigens fertig, siehe Anhang.
Tasten:
Links - Ein Byte zurück
Rechts - Ein Byte vor
Rauf - Eine Zeile rauf
Runter - Eine Zeile runter
TAB - Wechsel zwischen Hex- und ASCII-Spalten
2 x ESCAPE - Exit
Jede andere Taste bewirkt ein Ändern der aktuellen Speicherstelle.
In den HEX-Spalten:
- Es müssen 2 gültige Hex-Ziffern eingegeben werden, es werden
also nur 0-9, A-F oder a-f akzeptiert.
In den ASCII-Spalten:
- Es muss ein druckbares Zeichen eingeben werden.
Eingebene Werte ändern sofort WYSIWYG den Speicher. Die Anzeige wird
sowohl in der HEX- als auch in der ASCII-Spalte aktualisiert. Die
Eingabe muss NICHT mit CR (=Enter) bestätigt werden.
Man könnte jetzt noch die Bild-Tasten zum seitenweisen Blättern
einbauen, bzw. Pos1 und Ende zum Positionieren innerhalb der Zeilen
(Sprung zu Anfang, Ende). Ist relativ einfach, kostet aber zusätzlichen
Code im Binary. Ich weiß nur nicht, wieviel Komfort Du möchtest ;-)
Die ASCII-Anzeige habe ich noch erweitert: Es werden nun auch druckbare
8-Bit Zeichen wie Umlaute korrekt angezeigt. Dafür wichtig ist, dass
Deine Terminal-Emulation irgendeinen ISO8859-Zeichensatz (vorzugsweise
ISO8859-1 oder ISO8859-15) verwendet. UTF-8 ist dafür ungeeignet. Passt
auch nicht ins Retro-Muster ;-)
Viel Spaß,
Frank
Danke ! :-)
Läuft hexedit allein durch include des Headers oder muss ich es zu dem
anderen Grundmodul dazu linken?
>>Aha. Ich dachte, Du müsstest immer noch jedes mal ein EPROM brennen ;-)
Nur die ersten 100 Male.....
Christian J. schrieb:> Läuft hexedit allein durch include des Headers oder muss ich es zu dem> anderen Grundmodul dazu linken?
Du musst mcurses.c und hexedit.c zusammen kompilieren und linken. Wenn
Du schon ein main() hast (z.B. Dein Menü), kannst Du daraus ja hexedit()
aufrufen. In diesem Fall schmeisst Du das main() aus hexedit.c raus.
Hallo,
hier mal ein Gehäuse Tip gibt es ab und zu in der Bucht.
Ist ein altes Industrial Touch von HP Model 3082
Was ich Persönlich daran gut finde ist die Tastatur Matrix und das
Display mit der Filterscheibe die da verbaut sind.
Gruß Ronny
Frank M. schrieb:> Du musst mcurses.c und hexedit.c zusammen kompilieren und linken. Wenn
Dazu passend eine Antwort auf eine ältere Frage:
Christian J. schrieb:> es wird langsam Zeit sich> Gedanken um die Struktur der Software zu machen, uns ob Leo Makedatei> noch ausreicht aber ioch hoffe noch mit einem einzigen Verzeichnis> auszukommen und maximal 5-8 Quelldateien.
Ausreichend ist es für Deine Zwecke sicherlich. Inzwischen habe ich es
aber etwas ausgebaut. Die wichtigsten Erweiterungen sind"Autodependency
generation" und (optional) getrennte Build- und Output-Directories.
Zufügen/ändern/löschen von Headerdateien wird erkannt, und die
betreffenden C-Dateien werden ggf. neu compiliert.
Da SDCC viele Dateien generiert (.rel, .asm, .lst, .rst .sym und diverse
Dateien für Debugger), kann das Source-Verzeichnis schnell
unübersichtlich werden, wenn man alles in einem Verzeichnis läßt.
TODO:
- 'make clean' löscht z.Zt. zu wenig Dateien. Immerhin besser als
andersrum. ;)
- Variantenunterstützung (make debug/release)
- Schalter --fno-omit-frame-pointer abhängig von der SDCC-Version
setzen. Der Bug, für den der Schalter ein work araound ist, ist
ab SVN Revision #9096 gefixed.
- ...
Backup nicht vergessen.
Bei Fragen fragen.
Hi,
meine Mutter wäre stolz wenn meine Sockenschublade je so aufgeräumt
gewesen wäre wie dieses Skript!
Teste es mal (Backup vorher :-) und schaue wie es mit Unterverzeichnisse
klappt.
Christian J. schrieb:> Läuft hexedit allein durch include des Headers oder muss ich es zu dem> anderen Grundmodul dazu linken?
Die Frage erinnert mich daran, daß ich vorletzten Sonntag einen längeren
Artikel zu Deinem damals (tm) aktuellen Programm angefangen hatte, aber
kurz vor Fertig unterbrochen wurde. Das Meiste davon scheint noch
aktuell zu sein, deshalb jetzt doch noch der Text:
Christian J. schrieb:> kurze Rückmeldung. Nach fixer Umarbeitung des Source auf Makefile und> einigen "extern" die zugeführt werden mussten lief die Kiste auf Anhieb.
Wenn mit "Umarbeitung" war auch die Beseitigung der Includes von ganzen
C-Dateien gemeint war, dann wäre deren Verteidigung weiter unten ja
völlig überflüssig. Für den "Murks" gibts sowieso keine Rechtfertigung,
auch kein noch so suboptimaler Windowmanager.
Das C-Schlüsselwort 'extern' braucht man nur in seltenen Ausnahmefällen,
wenn man ordentliche Headerdateien hat.
> Weisst Du ob der Compiler feststehende Ausdrücke hat, um zb die Adresse> der Segmente (start und Ende) im Programmcode zu verarbeiten? Da würde> einiges vereinfachen wie zb Prüfsummen über den RAM Bereich usw.
Compiler- und Linker-Output anschauen? Mapfile, .sym- und .rst-Files?
Meiner Meinung nach solltest Du aber erst mal Dein bestehendes Gerüst
auf Vorderman bringen. Das fängt bei den Compiler-Warnungen an. Stand
Gestern warens ja nur zwei:
1
driver.c:93: warning 85: in function dump_memory unreferenced function argument : 'start'
2
driver.c:93: warning 85: in function dump_memory unreferenced function argument : 'ende'
3
main.c:123: warning 196: pointer target lost const qualifier
Sowas geht garnicht. Eigene Namen definieren für Standard-Datentypen ist
eine Unsitte, die nur Verwirrung stiftet. Andere machen das um kürzere
Namen schneller schreiben zu können (#define u8 unsigned char) oder weil
ihr Compiler zu alt ist. Die Namen, die Du definierst gibts seit ca. ISO
C99 (jedenfalls die sinnvollen).
--> #include <stdint.h>
einfügen, und Du hast sie.
1
#define bool unsigned int
Für bool würde ja auch ein char reichen. Allerdings gibts das seit ISO
C99 native als _Bool. SDCC hat das eingebaut und kann _Bool auch besser
optimieren als den selbst definierten Typ. Und wenn Du lieber bool statt
_Bool schreiben willst (und true/false statt 1/0)
--> #include <stdbool.h>
1
#define STACK_SIZE 0x00ff
2
#define RAM_START 0x2000
3
#define RAM_END (0xFFFF-STACK_SIZE)
4
#define RAM_SIZE (RAM_END-RAM_START)
5
#define ROM_START 0x0000
6
#define ROM_END 0x1fff
7
#define ROM_SIZE (ROM_END-ROM_START)
Laß Dir ROM_SIZE von Deinem Programm mal in dezimal ausgeben, und
vergleiche den Wert mit der Angabe im EPROM-Datenblatt. Das meine ich
wirklich so, ist ganz sicher eine nützliche Übung. Für RAM_SIZE gilt
analog das gleiche, aber da das RAM in Deiner Schaltung ja nicht
komplett addressiert wird, ist der Vergleich mit dem Datenblatt eher
sinnlos. Danach wäre dann der Stack dran. 254 Byte ist möglicherweise
etwas knapp,
aber nicht der Punkt auf den ich hinaus will.
Fehlermeldungen bei crt0.s. Menomic error, org in REL Area usw.
Die vorher nicht da waren.
#define uint8_t unsigned char
#define uint16_t unsigned int
#define sint8_t signed char
#define sint16_t signed int
Sowas geht garnicht.
Ich möchte das aber so haben. Für mich. :-) Schon mal was von MISRA
gehört?
Variablen werden da so definiert, vor jede kommt der Typ vor. Und da int
überall anders ist, hier 16Bit, beim ARM 32 ist das für mich leichter zu
merken.
u8_MeinName
Christian J. schrieb:> Fehlermeldungen bei crt0.s. Menomic error, org in REL Area usw.
so so
> Die vorher nicht da waren.
Was war denn vorher, und was ist nachher?
> #define uint8_t unsigned char> #define uint16_t unsigned int> #define sint8_t signed char> #define sint16_t signed int>> Sowas geht garnicht.>> Ich möchte das aber so haben. Für mich. :-)
Du hast den Text dazu nicht gelesen?
Lesen und darüber nachdenken ist in der kurzen Zeit ja auch nicht
möglich.
Das .org in REL Area nicht geht, weißt Du ja eigentlich. Das Makefile
kann da ganz bestimmt nix für. Kann es sein, daß Du mehrere crt0.s hast,
und jetzt eine andere genommen hast?
Den undefined-Error bekommst Du weg, wenn Du im Makefile zu den
Assembler-Optionen ein 'g' zufügst. Besser wäre es aber, die Symbole in
crt0.s als extern (.globl) zu deklarieren.
Spock'sche Logik:
Mit dem alten Make file ging es. alt = klein = weniger
Fehlermöglichkeiten.
Mit dem neuen makefile, auf die gleichen Sourcen los gelassen geht es da
nicht. neu = lang = mehr Fehler möglich.
Zeilen wie diese
define makedepend =
set -e
#$(CC) -MM $(CFLAGS) -o .dep/$(*F).d $<
(echo -n '$(OBJDIR)/'; $(CC) -MM $(CFLAGS) $< ) >.dep/$(*F).d
$(CP) .dep/$(*F).d .dep/$(*F).P
$(SED) -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
-e '/^$$/ d' -e 's/$$/ :/' < .dep/$(*F).d >> .dep/$(*F).P
$(RM) .dep/$(*F).d
endef
sind "menschenverachtend" :-)
Hier scheint es aber ok zu sein:
Immer noch Fehgler drin. mcursees compilieren geht gar nicht, weil der
den AVR da einbinden will. Sorry, kann nur scrrenshot anhängen, ist ein
putty Fenster.
PS: Keine Ahnung was diese krypischen zeichen bedeuten. sed finde ich
schrecklich. Muss man sich wohl einlesen...
cjulius@kirk:~/nasdata/Z80/src/ram$ make
/usr/bin/sdcc -mz80 --std-sdcc99 --opt-code-size
--fno-omit-frame-pointer -o build/main.rel -c main.c
at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer'
ignored
In file included from main.c:16:
mcurses.h:18:26: error: avr/pgmspace.h: No such file or directory
main.c:116: warning 85: in function main unreferenced local variable :
'buf'
/usr/bin/sdcc -mz80 --std-sdcc99 --opt-code-size
--fno-omit-frame-pointer -o build/driver.rel -c driver.c
at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer'
ignored
/usr/bin/sdcc -mz80 --std-sdcc99 --opt-code-size
--fno-omit-frame-pointer -o build/interrupt.rel -c interrupt.c
at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer'
ignored
/usr/bin/sdasz80 -plosff build/crt0.rel crt0.s
crt0.s:15: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:16: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:17: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:18: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:19: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:20: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:21: Error: <o> .org in REL area or directive / mnemonic error
crt0.s:55: Error: <u> undefined symbol encountered during assembly
crt0.s:78: Error: <u> undefined symbol encountered during assembly
crt0.s:98: Error: <u> undefined symbol encountered during assembly
crt0.s:101: Error: <u> undefined symbol encountered during assembly
crt0.s:125: Error: <u> undefined symbol encountered during assembly
removing build/crt0.rel
make: *** [build/crt0.rel] Fehler 2
cjulius@kirk:~/nasdata/Z80/src/ram$
Was ich witzig finde ist, dass der sdecc ins Bin File alles reinpackt,
ob es benutzt wird oder nicht. Sämtliche Routinen sind drin. Gibt es da
nicht eine Anaylse, was ausgehend von main.c alles eingebunden werden
muss und wer wen aufruft? Allein schon für die Stacksszie muss das ja
geprüft werden.
Version 3.1.0, der ist ja Asbach
Christian J. schrieb:> at 1: warning 117: unknown compiler option '--fno-omit-frame-pointer'
Di Option kennt er noch nicht, kannst Du dann auch rausnehmen.
> mcurses.h:18:26: error: avr/pgmspace.h: No such file or directory
Mach mal:
1
$ touch empty.c; sdcc -mz80 -E -dM empty.c
> /usr/bin/sdasz80 -plosff build/crt0.rel crt0.s> crt0.s:15: Error: <o> .org in REL area or directive / mnemonic error
...
> crt0.s:55: Error: <u> undefined symbol encountered during assembly
siehe oben
Version 3.4.1, die von gestern abend :-) Frisch kompiliert.
cjulius@kirk:~/nasdata/Z80/src/ram$ sdcc -v
SDCC :
mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/
hc08/s08/stm8 3.4.1 #9098 (Nov 9 2014) (Linux)
published under GNU General Public License (GPL)
cjulius@kirk:~/nasdata/Z80/src/ram$
>> Version 3.4.1, die von gestern abend :-) Frisch kompiliert.> Dann schreib den Pfad zu dieser Version in PREFIX.
Achso, wenn diese Version über $PATH der Shell gefunden wird, kannst Du
PREFIX im Makefile auch leer lassen. Das sollte sowieso der Default im
Muster-Makefile sein.
Ist das wichtig,. obh die von nachmittag oder abends war? Da kann es ja
nicht dran liegen. Da steht doch jeden Tag ne neue in den snapshots. Ich
habe erstmal auf altes Makefile zurück gebaut. Der Editor ist eh
selektiv und zeigt nur .c und .h an
Kannst du mir sagen, warum der sdcc alles in den bin File reinzieht?
Auch wenn die Main leer ist? Da muss man ja alles nachher löschen, was
man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht
einfach ist.
Oh Wunder.... sdcc liegt in /usr/local/bin, wenn man ihn über den make
instal installiert und in /usr/bin wenn man apt-get verwendet, zumindest
die asbach version.
bleibt noch übrig
cjulius@kirk:~/nasdata/Z80/src/ram$ make
/usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size
--fno-omit-frame-pointer -o build/main.rel -c main.c
main.c:116: warning 85: in function main unreferenced local variable :
'buf'
/usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size
--fno-omit-frame-pointer -o build/driver.rel -c driver.c
/usr/local/bin/sdcc -mz80 --std-sdcc99 --opt-code-size
--fno-omit-frame-pointer -o build/interrupt.rel -c interrupt.c
/usr/local/bin/sdasz80 -plosff build/crt0.rel crt0.s
/usr/local/bin/sdldz80 -n -f build/z80rom.lnk
?ASlink-Error-<cannot open> : "build/z80rom.lnk"
make: *** [build/z80rom.ihx] Fehler 3
cjulius@kirk:~/nasdata/Z80/src/ram$
Christian J. schrieb:> eine 3.1.0 noch. Shit!
Habe ich oben ja geschrieben.
Wenn ich in Deinem Makefile diese Zeile - Unter Beachtung des
darüberstehenden Kommentars - editiere, läuft das Makefile ohne Fehler
durch.
1
TARGETNAME = z80rom.bin
Da muß ich noch was abfangen...
Version 3.4.1:
1
#define __SDCC_z80 1
Version 3.4.1:
1
#define SDCC_z80 1
Auf das obere Makro wird von mcurses getestet...
> Ist das wichtig,. obh die von nachmittag oder abends war? Da kann es ja
Da hätte ich wohl ein Smiley hinmachen sollen.
Leo C. schrieb:> TARGETNAME = z80rom.bin>> Da muß ich noch was abfangen...
Mit und ohne .bin erzeugt es Fehlermeldung. Bin da ja auch dran, so wie
du grad und suche Fehler.
cjulius@kirk:~/nasdata/Z80/src/ram$ make
/usr/local/bin/sdldz80 -n -f build/z80ram.lnk
?ASlink-Error-<cannot open> : "build/z80ram.lnk"
make: *** [build/z80ram.ihx] Fehler 3
Nochmal:
Kannst du mir sagen, warum der sdcc alles in den bin File reinzieht?
Auch wenn die Main leer ist? Da muss man ja alles nachher löschen, was
man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht
einfach ist.
Lass das .bin an der Stelle auf jeden Fall weg. Auch wenn das Makefile
damit funktionieren würde, bekämst Du am Ende
z80rom.bin.hex und z80rom.bin.bin und z80rom.bin.map usw.
Glaube nicht, daß Du das möchtest.
Christian J. schrieb:> Kannst du mir sagen, warum der sdcc alles in den bin File reinzieht?> Auch wenn die Main leer ist? Da muss man ja alles nachher löschen, was> man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht> einfach ist.
SDCC hat halt einen recht konventionellen Linker. Sozusagen Retro halt.
Der Programmierer sagt dem Linker, was er linken soll, und das macht er
kann auch. Wenn Du prophylaktisch alles übergeben willst, was vielleicht
mal gebraucht werden könnte, kannst Du Dich ja mal mit Libraries
beschäftigen.
Der Compiler packt bisher aber auch nicht-referenzierte statische
Funktionen und Variablen (z.B. auch static inline Funktionen) in den
Output. Das wird vielleicht mal geändert. Ist bei einem
One-Pass-Compiler aber nicht so einfach.
Christian J. schrieb:> Da muss man ja alles nachher löschen, was> man nicht braucht? Bzw eine Abhängigkeits analyse machen was nicht> einfach ist.
Vorher erst garnicht reinschreiben, ist die bessere Alternative, und bei
Leuten, die wissen was sie tun, die übliche Praxis.
Es funktioniert leider auch ohnhe das bin nicht. Der Fehler kommt immer.
Und ich habe noch nie einen Compiler gesehen, der nicht benutzte
Funktionen nicht weg optmiert. Was nicht aufgerufen wird fliegt raus.
Der CCS macht das auch und ist nur 1-Pass, nur 1 Source File, alles
andere mit include einbinden. Kein Linker! Der Compiler macht doch eh
einen Baum auf wer wen anruft und was zurück kommt. Da kann man ja kein
Modul benutzen, wie das von Frank M.
Libs sind kompilierte dateien mit Header dran. Man bindet nur das ein
was man braucht. Ich habe 18 Jahre nie eine Lib benötigt oder je
geschrieben sondern immer nur Quelltext Libs, die ich in einem Unterverz
ablegte nund bei Beaarf reinholte. Nur bei VB gab es propietäre Libs,
die waren vorkompliiert, weil wir die ja mit der Interface Karte gekauft
hatten um eine Maschine anzusteuern.
Christian J. schrieb:> cjulius@kirk:~/nasdata/Z80/src/ram$ make> /usr/local/bin/sdldz80 -n -f build/z80ram.lnk> ?ASlink-Error-<cannot open> : "build/z80ram.lnk"> make: *** [build/z80ram.ihx] Fehler 3
Da make nix neu compiliert hat, sondern nur linken will, wurde
wahrscheinlich auch das linkfile "build/z80ram.lnk" nicht neu erzeugt.
Das alte heißt vielleicht noch "build/z80ram.bin.lnk" oder so.
Dann sollte ein 'make clean' helfen.
Bei mir funktionierts jedenfalls mit dem "ram.rar" von oben und den 2
Änderungen an PREFIX und TARGETNAME
Christian J. schrieb:> PS: Keine Ahnung was diese krypischen zeichen bedeuten. sed finde ich> schrecklich.
Da sind wir einer Meinung. Daran sieht man auch, daß der Kern dieses
"eingedosten Rezepts" ;) nicht von mir ist[1]. Ich hätte awk genommen...
[1] Was da gemacht wird ist an der Quelle erklärt, die ich ja auch
angegeben habe:
http://make.paulandlesley.org/autodep.html
Frank M. schrieb:> Unschön. Wieso eigentlich 2 mal 3.4.1? ;-)
Copy&paste Schlamperei.
> das#elif defined(__SDCC_z80)> durch#elif defined(__SDCC_z80) || defined(SDCC_z80)
Keine Ahnung, ob man die Variante ohne die führenden "__" noch
unterstützen muß. Die SDCC-Leute habe wohl auch gemerkt, daß das nicht
so gut ist.
Ich würde aber noch einen Schritt weiter gehen, und auf __SDCC testen
(oder "defined(__SDCC) || defined(SDCC)"). Dann gehts mit z180 (und all
den anderen) auch.
Christian J. schrieb:> Da kann man ja kein> Modul benutzen, wie das von Frank M.
Wenn man es benutzt muß es kompiliert und eingebunden werden. Wenn
nicht, dann nicht. Wo ist das Problem.
> Ich habe 18 Jahre nie eine Lib benötigt oder je> geschrieben sondern immer nur Quelltext Libs, die ich in einem Unterverz> ablegte nund bei Beaarf reinholte.
Eben bei Bedarf. Den Nicht-Bedarf erkennt der Linker halt nicht. Du aber
schon. Auch beim GNU Linker ist das Feature, daß nicht benötigte
Programmteile rauswirft, relativ neu.
Leo C. schrieb:> wahrscheinlich auch das linkfile "build/z80ram.lnk" nicht neu erzeugt.> Das alte heißt vielleicht noch "build/z80ram.bin.lnk" oder so.> Dann sollte ein 'make clean' helfen.
Nein, es geht nicht. .lnk wurd nicht gefunden und angemeckert. Kanste
mal die komplette make korrigiert wieder posten? Hier meines mit der
Änderung.
Dein Target heiß jetzt z80ram, aber das ist egal.
Das Makefile, mit dem es geht (mit den 2 Änderungen), ist hier im
Anhang:
Beitrag "Re: Retro Fieber: Z80 oder 68000 ?"
Die Unterschiede (und damit den neuen Fehler) müßtest Du leicht selber
finden.
nein, immer nioch das gleiche und deine Andeutungen verstehe ich leider
nicht woran es liegen könnte. diff brachte jetzt nicht die Erkenntnis
und z80ram oder rom dürfte egal sein. .lnk gibt es einfach nicht da wo
es sein sollte.
Leo C. schrieb:> Ich würde aber noch einen Schritt weiter gehen, und auf __SDCC testen> (oder "defined(__SDCC) || defined(SDCC)"). Dann gehts mit z180 (und all> den anderen) auch.
Ja, da hast Du recht. Warum sollte man sich unnötig auf den Z80
beschränken. Ich werde das abändern.
Das wird heute nix mehr. Bei Dir wird offensichtlich die Datei
'build/z80ram.lnk' nicht erzeugt. Woran das liegt, sieht man aber auch
in dem Log nicht. Es kann fast nur an der Umgebung liegen. Makefile und
der Rest der Dateien sind ja bei uns gleich.
Christian J. schrieb:> diff brachte jetzt nicht die Erkenntnis> und z80ram oder rom dürfte egal sein. .lnk gibt es einfach nicht da wo> es sein sollte.
Diff hilft mir oft. Meistens aber eins mit graphischer Oberfläche. Da
gibt es einige. Meld (kann auch ganze Verzeichnisbäume vergleichen),
fldiff, diffuse liegen hier rum. Sicher gibts noch andere.
Hier ist das auch mühsam, weil die Make-Versionen arg unterschiedlich
sind. Meins spricht Deutsch/Englisch-Kauderwelsch.
Ich spiele mir grad sdcc auf den PC rein, er kompiliert es grad.
Vielleicht liegt es auch daran dass Z80 Sachen bei mir auf dem Cubie
Truck gemacht werden, wo alle Daten als NAS liegen und über samba
erreichbar sind. Ich arbeite da nur mit nano, mc und Konsole. Der Z80
hängt da auch mit dran.
Schonn ein Unterschied, ob man mit Quadcore oder Cubie kompiliert :-)
Cubie: 2,5h, raspberry Pi 4h. PC ca 10 Minuten.
letzte Melduing:
ich kriege sdcc auf PC unter Mint 17 nicht installiert, da eine
GL...irgendwas LIB fehlt. Aus den paketquellen von Mint 17 kriege ich
nur die 3.3.0 raus.
Das make install bei dem Source endet mit einer fehlermeldung dass
Berechtigungen fehlen, die auch als root nicht behebar sind. Direktes
Düberkopieren der neuen sdcc Binaries in /usr/bin ergibt wieder eine
Fehlermeldung beim Aufruf, dass eine spezielle lib unter /usr/lib nicht
gefunden wird.
Vorerst auch keine Idee.....
edit: Ist installiert aber fehlermeldung bleibt. Also unter Debian auf
Cubitruck und auf PC das Gleiche.
Frank M. schrieb:> Tasten:>> Links - Ein Byte zurück> Rechts - Ein Byte vor> Rauf - Eine Zeile rauf> Runter - Eine Zeile runter> TAB - Wechsel zwischen Hex- und ASCII-Spalten> 2 x ESCAPE - Exit
Hallo Frank,
ich habe das grad getestet. Läuft jetzt! Fehler lag bei mir in dem
Ringpuffer. Verbesserungsvorschlag: Nach Eingabe eines Hex wertes in die
nächstes Spalte springen. Hochscrollen und wieder runter läuft noch
nicht, da springt er einfach raus und beendet es,. Tritt aber nur bei
tastenwiderholung auf, einzeltasten drücken klappt es. Eher meine
Hardware, da zu langsam und kein Duplex.
Bleibt noch die Frage: wieso getch() und nicht mehr getchar() ? getchar
ist bei mir überschrieben durch eine eigene Funktion, getch aber ncht.
Christian J. schrieb:> ich habe das grad getestet. Läuft jetzt! Fehler lag bei mir in dem> Ringpuffer. Verbesserungsvorschlag: Nach Eingabe eines Hex wertes in die> nächstes Spalte springen.
Ja, habe ich auch schon daran gedacht. Hast Du mal mit der
Tabulator-Taste rechts in die ASCII-Darstellung gewechselt und dort
schon ein paar Bytes geändert, z.B. Deine Z80-Mini-System-Meldung?
> Hochscrollen und wieder runter läuft noch> nicht, da springt er einfach raus und beendet es.
Ein eindeutiges Signal, dass Dein getchar Zeichen verschluckt - also
nicht schnell genug die Zeichen abholt. Wenn Du eine der Cursor-Tasten
runterdrückst, dann schickt das Terminal wiederholt <ESC>[D, also z.B.
<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D.
Der Hex-Editor beendet sich bei 2x <ESC> hintereinander, d.h.
irgendwann/irgendwo werden [D verschluckt und mcurses sieht 2x <ESC>. Da
musst Du noch dran arbeiten, das muss besser gehen. Soooo schnell
repetiert Deine Tastatur auch nicht. Irgendwo steckt noch der Wurm in
Deinem Ringbuffer.
> Tritt aber nur bei> tastenwiderholung auf, einzeltasten drücken klappt es. Eher meine> Hardware, da zu langsam und kein Duplex.
Ja, siehe oben.
> Bleibt noch die Frage: wieso getch() und nicht mehr getchar() ? getchar> ist bei mir überschrieben durch eine eigene Funktion, getch aber ncht.
Du hast es immer noch nicht verstanden, oder? getch() ist die
High-Level-mcurses-Funktion, welche sich mittels (u.U. mehrfachem)
getchar()-Aufruf die Zeichen holt und solche Escapesequenzen, wie
"<ESC>[D" zu einem Tastencode KEY_DOWN zusammenfasst.
Denk Dir das wie ein Schichtenmodell:
Applikation hexedit() sieht KEY_DOWN
|
mcurses getch() <ESC>[D -> KEY_DOWN
|
low-level-IO getchar() sieht <ESC>, dann [, dann D
|
SIO-Device Deine I/O-Fktn. liest SIO
Die Applikation benutzt getch() oder getnstr(), um Tasten oder ganze
Strings einzulesen, getch() ruft mehrmals getchar() auf, um die Zeichen
einzusammeln, die zu EINEM Tastendruck gehören. Bei den Cursor-Tasten
muss getch() dreimal(!) getchar() aufrufen! Die Applikation bekommt bei
getch() aber nur EINEN Tastencode, nämlich KEY_DOWN.
Die mcurses-Funktionen (s. MCURSES) sind die High-Level-Funktionen.
Wenn die Applikation mcurses benutzt, dann darf die Anwendung
ausschließlich über mcurses die Interaktion machen. Für die
Applikation sind dann getchar()/putchar() usw. verboten und
ausschließlich den internen mcurses-Funktionen vorbehalten. Sonst gibt's
Zeichensalat!
Dieses hier schrieb ich Dir hier schon vor ein paar Tagen:
Alt (stdio) Neu (mcurses)
=============================
getchar() getch()
putchar() addch()
puts() addstr()
---- move()
usw. usw.
Christian J. schrieb:> Hochscrollen und wieder runter läuft noch> nicht, da springt er einfach raus und beendet es,.
Noch etwas dazu: Wenn Du oben anschlägst, wird nicht nur der
scroll-Befehl ans Terminal geschickt, sondern auch knapp 80 Zeichen, um
die neue Zeile unten/oben einzublenden.
Ich hoffe, Du hast auch für die Ausgabe einen interrupt-gesteuerten
Ringbuffer. Denn während die 80 Zeichen geschickt werden, sendet Deine
Tastatur weiter
<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D, wenn Du die
Cursor-Taste runterhältst. Wir haben es hier mit FullDuplex zu tun!
Sowohl Input und Output müssen über Interrupts laufen. Insbesondere
Deine Output-Funktion darf NICHT warten, bis das Zeichen komplett
gesendet wurde. Sonst bist Du verratzt und verkauft.
Frank M. schrieb:> Ich hoffe, Du hast auch für die Ausgabe einen interrupt-gesteuerten> Ringbuffer. Denn während die 80 Zeichen geschickt werden, sendet Deine> Tastatur weiter> <ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D<ESC>[D, wenn Du die> Cursor-Taste runterhältst. Wir haben es hier mit FullDuplex zu tun!
Hallo Frank,
ja, das weiss ich schon, bin ja auch schon weiter. Ich habe nur Halb
Duplex und ich werde auch den Sendebuffer schreiben müssen. Mit 9600 ist
das ganze auch recht langsam aber durchaus interessant. Ich mache hier
erstmal einen Break bis ich hier weiter bin.
>Insbesondere Deine Output-Funktion darf NICHT warten, bis das Zeichen >komplett
gesendet wurde. Sonst bist Du verratzt und verkauft.
Tut sie aber (noch) :-O
Christian J. schrieb:>> Insbesondere Deine Output-Funktion darf NICHT warten, bis das Zeichen>> komplett gesendet wurde. Sonst bist Du verratzt und verkauft.>> Tut sie aber (noch) :-O
Tut sie nicht.
Wahrscheinlich ein Mißverständnis.
1
// Zeichenausgabe für printf auf der STI mit 9600 Baud
2
voidputchar(charc)
3
{
4
while((STI_TSR&0x80)==0);// Warte bis Buffer frei...
5
STI_UDR=c;// Byte einschreiben
6
7
}
0x80 ist das "Transmit-Buffer-Empty"-Flag. Deine Routine wartet also,
bis ein neues Zeichen im Transmitbuffer passt. Mit dem Senden des
vorhergehenden Zeichens wurde dann gerade erst begonnen. Den erratzten
Fall hättest Du, wenn Du auf das "End-Of-Transmission"-Flag warten
würdest.