Hallo,
ist irgendwie blöde extra einen Thread dafür aufzumachen aber es stellt
sich die Frage wie man bei der printf Funktion die Standardausgabe
überschreibt? Bzw. überhaupt herausfindet welches diese ist? Denn die
z80.lib liegt nur in kompilierter Form vor und da liegt die drin. Im
Manual wird nur vom mcs51 gesprochen und das ist ein Controller mit
Uart, der Z80 aber ein Prozessor ohne Peripherie.
Reicht es eine eigene putchar (char c) irgendwo im Source zu haben? Oder
muss man den Umweg über sprintf(buffer,...) gehen und dann über die
eigene putchar ausgeben?
Gruss,
Christian
Christian J. schrieb:> Hallo,>> ist irgendwie blöde extra einen Thread dafür aufzumachen aber es stellt> sich die Frage wie man bei der printf Funktion die Standardausgabe> überschreibt?
Use the Source Luke.
> Bzw. überhaupt herausfindet welches diese ist?
UTSL
> Denn die z80.lib liegt nur in kompilierter Form vor und da liegt die> drin.
Du behauptest allen Ernstes, ein Open Source Compiler würde ohne
Sourcecode der zugehörigen libs veröffentlicht?
> Reicht es eine eigene putchar (char c) irgendwo im Source zu haben?
Klar, wenn Du dafür sorgst, daß der Linker Deine nimmt, statt der
Version aus der libc. Du kannst auch die libc-Version austauschen, oder
die letztere mal anschauen (Anhang, liegt bei Debian in
/usr/share/sdcc/lib/src/z80). Die läd das auszugebende Zeichen in
Register L und ruft einen RST 08 auf. Dies dürfte wohl auf die
Debugger-Umgbung mit ucsim abgestimmt sein.
Und wenn man sich da mal durchwühlt durch die printf findet man heraus,
dass immer auf eine outputchar() vom Typ pfn_outputchar verwiesen wird
und wohin die ausgibt erklärt sich zumindest mir nich aus dem Kontext.
Christian J. schrieb:> Und wenn man sich da mal durchwühlt durch die printf findet man heraus,> dass immer auf eine outputchar() vom Typ pfn_outputchar verwiesen wird> und wohin die ausgibt erklärt sich zumindest mir nich aus dem Kontext.
Der Funktionszeiger heißt output_char und nicht outputchar. Kein
Wunder, daß Du so nichts findest. Außerdem ist das nicht "immer" so,
sondern nur in 'printf_large.c', und nicht in den anderen Varianten.
Für Z80 ist das aber die einzig interessante Variante.
1
>#ifndefSDCC_STACK_AUTO
Da der Z80 einen vernünftigen Stack hat, ist dieses Macro
sinnvollerweise immer defined. Also können wir alles mit SDCC_STACK_AUTO
undefined ausblenden.
Die Funktion, die ein Zeichen ausgibt, wird als erster Parameter ('pfn')
an _print_format() übergeben.
_print_format() wird von printf(), vprintf(), sprintf() und vsprintf()
aufgerufen.
Den Rest findest Du selber.
Vielleicht solltest du die Antworten auf deine Frage mal lesen. Ich habe
dir sogar mal funktionierenden Beispielcode für printf mit SDCC und SFRs
vor die Nase geworfen. Den hast du aber ignoriert und nach "mehr
Beispielcode" gefragt. Mehr Silbertablett gibt's von mir nicht.
Tipp: Ausprobieren. Einfach mal ein printf("hallo welt") programmieren.
Das sollte dir einen Linkerfehler schenken, aus dem du genau rauslesen
kannst, was du tun musst, um printf auf deinem System hinzubekommen. So
ein bisschen C hinklappern solltest du schon können.
@S.R. Ich kenne den Codefetzen, das funktioniert aber nicht mehr. Wüsste
auch keinen Grund warum er deine putchar nehmen sollte.
Macht man es so, erhält man im map File den Veweis auf die eigene
Routine. Eine manuelle Suche im Hex Dump Code ergab, dass es keinen CALL
/ JMP etc auf meine putchar gibt.
1
Files Linked [ module(s) ]
2
3
main.rel [ main ]
4
crt0.rel [ crt0 ]
5
6
7
Libraries Linked [ object file ]
8
9
/usr/local/bin/../share/sdcc/lib/z80/z80.lib
10
[ vprintf.rel ]
11
/usr/local/bin/../share/sdcc/lib/z80/z80.lib
12
[ printf_large.rel ]
13
/usr/local/bin/../share/sdcc/lib/z80/z80.lib
14
[ strlen.rel ]
15
/usr/local/bin/../share/sdcc/lib/z80/z80.lib
16
[ crtcall.rel ]
Das einzige was zu finden ist, ist das hier in einer putchar.s. Und das
ist einkompiliert in die Z80-Lib. Also würde mir nur noch einfallen die
putchar.s als eigenes File mit einzulinken, getrennt zu übersetzen und
in Asm dort meine Uart anzusprechen.
Und wenn alles nicht geht eben printf(buf,....)
Ich hätte sicher nicht gefragt, wenn ich es wüsste. Egal, ich kriege es
sicher irgendwann raus....
putchar::
_putchar_rr_s::
ld hl,#2
add hl,sp
ld l,(hl)
ld a,#1
rst 0x08
ret
_putchar_rr_dbs::
ld l,e
ld a,#1
rst 0x08
ret
S. R. schrieb:> Vielleicht solltest du die Antworten auf deine Frage mal lesen. Ich habe
Im sdcc-Forum auf Sourceforge wurde ihm ja auch noch ein möglicher Weg
gezeigt...
Christian J. schrieb:> Macht man es so, erhält man im map File den Veweis auf die eigene> Routine.> Eine manuelle Suche im Hex Dump Code ergab, dass es keinen CALL> / JMP etc auf meine putchar gibt.
Kunststück, putchar wird ja über einen Funktionspointer aufgerufen.
Schon vergessen?
Du kanst ja mal in Deinem Hexdump nach E9 suchen, Opcode für 'JP (HL)'.
Und dann nach den Stellen, an denen ein Call darauf steht.
> Das einzige was zu finden ist, ist das hier in einer putchar.s. Und das> ist einkompiliert in die Z80-Lib.
Das putchar() aus der Lib wird aber nicht verwendet, wenn der Linker ein
anderes findet. Ansonsten bekämst Du nämlich einen "Multible defined
error" oder so.
> Also würde mir nur noch einfallen die> putchar.s als eigenes File mit einzulinken, getrennt zu übersetzen
In welcher Datei die Funktion (das Symbol) steht, ist dem Linker völlig
Wurst.
> und in Asm dort meine Uart anzusprechen.
Ob C oder Assembler ist auch Wurst.
Christian J. schrieb:> @S.R. Ich kenne den Codefetzen, das funktioniert aber nicht mehr. Wüsste> auch keinen Grund warum er deine putchar nehmen sollte.
Vielleicht, weil ein Überschreiben von putchar einfach mal vorgesehen
ist. Der Linker ist vielleicht nicht ganz so intelligent wie ein Sack
Holz, aber schwach definierte Symbole kennt er immerhin. Aber gut, wer
nicht will der hat schon. Ich klinke mich dann mal aus.