From a82379b1f3774be69fced4056a6a4cab6b598ea3 Mon Sep 17 00:00:00 2001 From: VinceAle7082 Date: Fri, 2 Aug 2024 19:28:04 +0200 Subject: [PATCH] Half implemented printf (doesn't compile) --- src/bootloader/stage2/stdio.c | 257 +++++++++++++++++++--------------- 1 file changed, 147 insertions(+), 110 deletions(-) diff --git a/src/bootloader/stage2/stdio.c b/src/bootloader/stage2/stdio.c index 13b54c5..6820e04 100644 --- a/src/bootloader/stage2/stdio.c +++ b/src/bootloader/stage2/stdio.c @@ -15,26 +15,29 @@ void puts(const char *str) } #define PRINTF_STATE_NORMAL 0 -#define PRINTF_STATE_LENGHT 1 -#define PRINTF_STATE_LENGHT_SHORT 2 -#define PRINTF_STATE_LENGHT_LONG 1 +#define PRINTF_STATE_LENGTH 1 +#define PRINTF_STATE_LENGTH_SHORT 2 +#define PRINTF_STATE_LENGTH_LONG 3 #define PRINTF_STATE_SPEC 4 + #define PRINTF_LENGTH_DEFAULT 0 #define PRINTF_LENGTH_SHORT_SHORT 1 #define PRINTF_LENGTH_SHORT 2 #define PRINTF_LENGTH_LONG 3 #define PRINTF_LENGTH_LONG_LONG 4 -int* printf_number(int *argp, int length, bool sign, int radix) -const char g_HexChars[] = '0123456789abcdef' + +int * printf_number(int *argp, int length, bool sign, int radix); void _cdecl printf(const char *fmt, ...) { - int *argp = (int*)&fmt; + int *argp = (int *)&fmt; int state = PRINTF_STATE_NORMAL; int length = PRINTF_LENGTH_DEFAULT; int radix = 10; bool sign = false; + argp++; + while (*fmt) { switch (state) @@ -43,170 +46,204 @@ void _cdecl printf(const char *fmt, ...) switch (*fmt) { case '%': - state = PRINTF_STATE_LENGHT; + state = PRINTF_STATE_LENGTH; break; default: putc(*fmt); break; } - - case PRINTF_STATE_LENGHT: + break; + + case PRINTF_STATE_LENGTH: switch (*fmt) { case 'h': length = PRINTF_LENGTH_SHORT; - state = PRINTF_STATE_LENGHT_SHORT; + state = PRINTF_STATE_LENGTH_SHORT; break; - case 'l': + case 'l': length = PRINTF_LENGTH_LONG; - state = PRINTF_STATE_LENGHT_LONG; + state = PRINTF_STATE_LENGTH_LONG; break; - default: - goto PRINTF_STATE_SPEC; + goto PRINTF_STATE_SPEC_; } break; - case PRINTF_LENGTH_SHORT: + case PRINTF_STATE_LENGTH_SHORT: if (*fmt == 'h') { length = PRINTF_LENGTH_SHORT_SHORT; state = PRINTF_STATE_SPEC; } else - { - goto PRINTF_STATE_SPEC; - } + goto PRINTF_STATE_SPEC_; break; - + + case PRINTF_STATE_LENGTH_LONG: + if (*fmt == 'l') + { + length = PRINTF_LENGTH_LONG_LONG; + state = PRINTF_STATE_SPEC; + } + else + goto PRINTF_STATE_SPEC_; + break; + case PRINTF_STATE_SPEC: + PRINTF_STATE_SPEC_: switch (*fmt) { - case 'c': - putc((char)*argp); + case 'c': + putc((char)*argp); + argp++; + break; + + case 's': + if (length == PRINTF_LENGTH_LONG || length == PRINTF_LENGTH_LONG_LONG) + { + puts_f(*(const char far **)argp); + argp += 2; + } + else + { + puts(*(const char **)argp); argp++; - break; - case 's': - puts(*(char **)argp); - argp++; - break; - case '%': - putc('%'); - break; - case 'd': - case 'i': - radix = 10; - sign = true; - argp = printf_number(argp, length, sign, radix); - break; - case 'u': - radix = 10; - sign = false; - argp = printf_number(argp, length, sign, radix); - break; - case 'x': - case 'X': - case 'p': - radix = 16; - sign = false; - argp = printf_number(argp, length, sign, radix); - break; - case 'o': - radix = 8; - sign = false; - argp = printf_number(argp, length, sign, radix); - break; - //Se รจ messo un carattere non valido questo codice fa in modo che li ignora. - default: - break; + } + break; + + case '%': + putc('%'); + break; + + case 'd': + case 'i': + radix = 10; + sign = true; + argp = printf_number(argp, length, sign, radix); + break; + + case 'u': + radix = 10; + sign = false; + argp = printf_number(argp, length, sign, radix); + break; + + case 'X': + case 'x': + case 'p': + radix = 16; + sign = false; + argp = printf_number(argp, length, sign, radix); + break; + + case 'o': + radix = 8; + sign = false; + argp = printf_number(argp, length, sign, radix); + break; + + // ignore invalid spec + default: + break; } - //Porta le variabili allo stato di default / normale. + + // reset state state = PRINTF_STATE_NORMAL; length = PRINTF_LENGTH_DEFAULT; radix = 10; sign = false; break; } + fmt++; } } -int* printf_number(int* argp, int length, bool sign, int radix) +const char g_HexChars[] = "0123456789abcdef"; + +int *printf_number(int *argp, int length, bool sign, int radix) { char buffer[32]; unsigned long long number; int number_sign = 1; int pos = 0; + // process length switch (length) { - case PRINTF_LENGTH_SHORT_SHORT: - case PRINTF_LENGTH_SHORT: - case PRINTF_LENGTH_LONG: - if (sign) + case PRINTF_LENGTH_SHORT_SHORT: + case PRINTF_LENGTH_SHORT: + case PRINTF_LENGTH_DEFAULT: + if (sign) + { + int n = *argp; + if (n < 0) { - long int n = *(long int*)argp; - if (n < 0) - { - n = -n; - number_sign = -1; - } - number = (unsigned long long)n; + n = -n; + number_sign = -1; } - else - { - number = (*unsigned long int*)argp; - } - argp += 2; - break; - case PRINTF_LENGTH_LONG_LONG: - if (sign) - { - long long int n = *(long long int*)argp; - if (n < 0) - { - n = -n; - number_sign = -1; - } - number = (unsigned long long)n; - } - else - { - number = (*unsigned long long int *)argp; - } - argp += 4; - break; - case PRINTF_LENGTH_DEFAULT: - if (sign) - { - int n = *argp; - if (n < 0) - { - n = -n; - number_sign = -1; - } - number = n; - } - else - { - number = (*unsigned int*)argp; + number = (unsigned long long)n; + } + else + { + number = *(unsigned int *)argp; + } + argp++; + break; + case PRINTF_LENGTH_LONG: + if (sign) + { + long int n = *(long int *)argp; + if (n < 0) + { + n = -n; + number_sign = -1; } - argp++; - break; + number = (unsigned long long)n; + } + else + { + number = *(unsigned long int *)argp; + } + argp += 2; + break; + + case PRINTF_LENGTH_LONG_LONG: + if (sign) + { + long long int n = *(long long int *)argp; + if (n < 0) + { + n = -n; + number_sign = -1; + } + number = (unsigned long long)n; + } + else + { + number = *(unsigned long long int *)argp; + } + argp += 4; + break; } + + // convert number to ASCII do { - uint32_t rem = number % radix; + uint32_t rem; + x86_div64_32(number, radix, &number, &rem); buffer[pos++] = g_HexChars[rem]; } while (number > 0); + // add sign if (sign && number_sign < 0) - { buffer[pos++] = '-'; - } + // print number in reverse order while (--pos >= 0) putc(buffer[pos]); + return argp; } \ No newline at end of file