1 /** Simple printf implementation
2 Again a stub - will use the std one later...
7 /* A hack because I dont understand how va_arg works...
8 sdcc pushes right to left with the real sizes, not cast up
10 so printf(int, char, long)
11 results in push long, push char, push int
12 On the z80 the stack grows down, so the things seem to be in
16 typedef char * va_list;
17 #define va_start(list, last) list = (char *)&last + sizeof(last)
18 #define va_arg(list, type) *(type *)list; list += sizeof(type);
20 typedef void EMIT(char c, void *pData);
23 static void _printn(unsigned u, unsigned base, char issigned, EMIT *emitter, void *pData)
25 const char *_hex = "0123456789ABCDEF";
26 if (issigned && ((int)u < 0)) {
27 (*emitter)('-', pData);
28 u = (unsigned)-((int)u);
31 _printn(u/base, base, 0, emitter, pData);
32 (*emitter)(_hex[u%base], pData);
35 static void _printf(const char *format, EMIT *emitter, void *pData, va_list va)
41 char c = va_arg(va, char);
47 unsigned u = va_arg(va, unsigned);
48 _printn(u, 10, 0, emitter, pData);
53 unsigned u = va_arg(va, unsigned);
54 _printn(u, 10, 1, emitter, pData);
59 unsigned u = va_arg(va, unsigned);
60 _printn(u, 16, 0, emitter, pData);
65 char *s = va_arg(va, char *);
67 (*emitter)(*s, pData);
74 (*emitter)(*format, pData);
82 static void _char_emitter(char c, void *pData)
87 void printf(const char *format, ...)
92 _printf(format, _char_emitter, NULL, va);