diff --git a/src/bootloader/stage2/Makefile b/src/bootloader/stage2/Makefile
index da46177..1c25129 100644
--- a/src/bootloader/stage2/Makefile
+++ b/src/bootloader/stage2/Makefile
@@ -1,9 +1,8 @@
 BUILD_DIR?=build/
 ASM?=nasm
 ASMFLAGS?=-f obj
-CC?=gcc
 CC16?=/usr/bin/watcom/binl/wcc
-CFLAGS16?= -4 -d3 -s -wx -ms -zl -zq
+CFLAGS16?=-4 -d3 -s -wx -ms -zl -zq # -oneatxzh 
 LD16?=/usr/bin/watcom/binl/wlink
 
 SOURCES_C=$(wildcard *.c)
@@ -11,7 +10,7 @@ SOURCES_ASM=$(wildcard *.asm)
 OBJECTS_C=$(patsubst %.c, $(BUILD_DIR)/stage2/c/%.obj, $(SOURCES_C))
 OBJECTS_ASM=$(patsubst %.asm, $(BUILD_DIR)/stage2/asm/%.obj, $(SOURCES_ASM))
 
-.PHONY: all clean always
+.PHONY: all stage2 clean always
 
 all: stage2
 
diff --git a/src/bootloader/stage2/linker.lnk b/src/bootloader/stage2/linker.lnk
index 2942bbb..612fed6 100644
--- a/src/bootloader/stage2/linker.lnk
+++ b/src/bootloader/stage2/linker.lnk
@@ -1,12 +1,12 @@
 FORMAT RAW BIN
 OPTION QUIET,
-    NODEFAULTLIBS,
-    START=entry,
-    VERBOSE,
-    OFFSET=0,
-    STACK=0X200
+       NODEFAULTLIBS,
+       START=entry,
+       VERBOSE,
+       OFFSET=0,
+       STACK=0x200
 ORDER
     CLNAME CODE
         SEGMENT _ENTRY
         SEGMENT _TEXT
-    CLNAME DATA
+    CLNAME DATA
\ No newline at end of file
diff --git a/src/bootloader/stage2/main.asm b/src/bootloader/stage2/main.asm
new file mode 100644
index 0000000..694c448
--- /dev/null
+++ b/src/bootloader/stage2/main.asm
@@ -0,0 +1,22 @@
+bits 16
+
+section _ENTRY class=CODE
+
+extern _cstart_
+global entry
+
+entry:
+    cli
+
+    mov ax, ds
+    mov ss, ax
+    mov sp, 0
+    mov bp, sp
+    sti
+
+    xor dh, dh
+    push dx
+    call _cstart_
+
+    cli
+    hlt
diff --git a/src/bootloader/stage2/main.c b/src/bootloader/stage2/main.c
index 1e7137d..49fcd6f 100644
--- a/src/bootloader/stage2/main.c
+++ b/src/bootloader/stage2/main.c
@@ -3,6 +3,11 @@
 
 void _cdecl cstart_(uint16_t bootDrive)
 {
-    puts("Hello World from the Stage 2 of the bootloader written in C!");
+    const char far* far_str = "far string";
+
+    puts("Hello world from stage 2 of the bootloader written in C!\r\n");
+    printf("Formatted %% %c %s %ls\r\n", 'a', "string", far_str);
+    printf("Formatted %d %i %x %p %o %hd %hi %hhu %hhd\r\n", 1234, -5678, 0xdead, 0xbeef, 012345, (short)27, (short)-42, (unsigned char)20, (signed char)-10);
+    printf("Formatted %ld %lx %lld %llx\r\n", -100000000l, 0xdeadbeeful, 10200300400ll, 0xdeadbeeffeebdaedull);
     for (;;);
-}
\ No newline at end of file
+}
diff --git a/src/bootloader/stage2/stdint.h b/src/bootloader/stage2/stdint.h
index 2999fd9..9ea757e 100644
--- a/src/bootloader/stage2/stdint.h
+++ b/src/bootloader/stage2/stdint.h
@@ -6,9 +6,12 @@ typedef signed short int16_t;
 typedef unsigned short uint16_t;
 typedef signed long int int32_t;
 typedef unsigned long int uint32_t;
-typedef signed long int int64_t;
-typedef unsigned long int uint64_t;
+typedef signed long long int int64_t;
+typedef unsigned long long int uint64_t;
+
 typedef uint8_t bool;
 
-#define true 1
 #define false 0
+#define true 1
+
+
diff --git a/src/bootloader/stage2/stdio.c b/src/bootloader/stage2/stdio.c
index c9aa479..9cc6d21 100644
--- a/src/bootloader/stage2/stdio.c
+++ b/src/bootloader/stage2/stdio.c
@@ -5,7 +5,17 @@ void putc(char c)
 {
     x86_Video_WriteCharTeletype(c, 0);
 }
-void puts(const char *str)
+
+void puts(const char* str)
+{
+    while(*str)
+    {
+        putc(*str);
+        str++;
+    }
+}
+
+void puts_f(const char far* str)
 {
     while(*str)
     {
@@ -26,11 +36,11 @@ void puts(const char *str)
 #define PRINTF_LENGTH_LONG          3
 #define PRINTF_LENGTH_LONG_LONG     4
 
-int * printf_number(int *argp, int length, bool sign, int radix);
+int* printf_number(int* argp, int length, bool sign, int radix);
 
-void _cdecl printf(const char *fmt, ...)
+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;
@@ -42,118 +52,97 @@ void _cdecl printf(const char *fmt, ...)
     {
         switch (state)
         {
-        case PRINTF_STATE_NORMAL:
-            switch (*fmt)
-            {
-            case '%':
-                state = PRINTF_STATE_LENGTH;
-                break;
-            default:
-                putc(*fmt);
-                break;
-            }
-            break;
-
-        case PRINTF_STATE_LENGTH:
-            switch (*fmt)
-            {
-            case 'h':
-                length = PRINTF_LENGTH_SHORT;
-                state = PRINTF_STATE_LENGTH_SHORT;
-                break;
-            case 'l':
-                length = PRINTF_LENGTH_LONG;
-                state = PRINTF_STATE_LENGTH_LONG;
-                break;
-            default:
-                goto PRINTF_STATE_SPEC_;
-            }
-            break;
-
-        case PRINTF_STATE_LENGTH_SHORT:
-            if (*fmt == 'h')
-            {
-                length = PRINTF_LENGTH_SHORT_SHORT;
-                state = PRINTF_STATE_SPEC;
-            }
-            else
-                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);
-                argp++;
-                break;
-
-            case 's':
-                if (length == PRINTF_LENGTH_LONG || length == PRINTF_LENGTH_LONG_LONG)
+            case PRINTF_STATE_NORMAL:
+                switch (*fmt)
                 {
-                    puts_f(*(const char far **)argp);
-                    argp += 2;
-                }
-                else
-                {
-                    puts(*(const char **)argp);
-                    argp++;
+                    case '%':   state = PRINTF_STATE_LENGTH;
+                                break;
+                    default:    putc(*fmt);
+                                break;
                 }
                 break;
 
-            case '%':
-                putc('%');
+            case PRINTF_STATE_LENGTH:
+                switch (*fmt)
+                {
+                    case 'h':   length = PRINTF_LENGTH_SHORT;
+                                state = PRINTF_STATE_LENGTH_SHORT;
+                                break;
+                    case 'l':   length = PRINTF_LENGTH_LONG;
+                                state = PRINTF_STATE_LENGTH_LONG;
+                                break;
+                    default:    goto PRINTF_STATE_SPEC_;
+                }
                 break;
 
-            case 'd':
-            case 'i':
-                radix = 10;
-                sign = true;
-                argp = printf_number(argp, length, sign, radix);
+            case PRINTF_STATE_LENGTH_SHORT:
+                if (*fmt == 'h')
+                {
+                    length = PRINTF_LENGTH_SHORT_SHORT;
+                    state = PRINTF_STATE_SPEC;
+                }
+                else goto PRINTF_STATE_SPEC_;
                 break;
 
-            case 'u':
+            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);
+                                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 '%':   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;
+
+                    default:    break;
+                }
+
+                state = PRINTF_STATE_NORMAL;
+                length = PRINTF_LENGTH_DEFAULT;
                 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;
-            }
-
-            // reset state
-            state = PRINTF_STATE_NORMAL;
-            length = PRINTF_LENGTH_DEFAULT;
-            radix = 10;
-            sign = false;
-            break;
         }
 
         fmt++;
@@ -162,88 +151,84 @@ void _cdecl printf(const char *fmt, ...)
 
 const char g_HexChars[] = "0123456789abcdef";
 
-int *printf_number(int *argp, int length, bool sign, int radix)
+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_DEFAULT:
-        if (sign)
-        {
-            int n = *argp;
-            if (n < 0)
+        case PRINTF_LENGTH_SHORT_SHORT:
+        case PRINTF_LENGTH_SHORT:
+        case PRINTF_LENGTH_DEFAULT:
+            if (sign)
             {
-                n = -n;
-                number_sign = -1;
+                int n = *argp;
+                if (n < 0)
+                {
+                    n = -n;
+                    number_sign = -1;
+                }
+                number = (unsigned long long)n;
             }
-            number = (unsigned long long)n;
-        }
-        else
-        {
-            number = *(unsigned int *)argp;
-        }
-        argp++;
-        break;
+            else
+            {
+                number = *(unsigned int*)argp;
+            }
+            argp++;
+            break;
 
-    case PRINTF_LENGTH_LONG:
-        if (sign)
-        {
-            long int n = *(long int *)argp;
-            if (n < 0)
+        case PRINTF_LENGTH_LONG:
+            if (sign)
             {
-                n = -n;
-                number_sign = -1;
+                long int n = *(long int*)argp;
+                if (n < 0)
+                {
+                    n = -n;
+                    number_sign = -1;
+                }
+                number = (unsigned long long)n;
             }
-            number = (unsigned long long)n;
-        }
-        else
-        {
-            number = *(unsigned long int *)argp;
-        }
-        argp += 2;
-        break;
+            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)
+        case PRINTF_LENGTH_LONG_LONG:
+            if (sign)
             {
-                n = -n;
-                number_sign = -1;
+                long long int n = *(long long int*)argp;
+                if (n < 0)
+                {
+                    n = -n;
+                    number_sign = -1;
+                }
+                number = (unsigned long long)n;
             }
-            number = (unsigned long long)n;
-        }
-        else
-        {
-            number = *(unsigned long long int *)argp;
-        }
-        argp += 4;
-        break;
+            else
+            {
+                number = *(unsigned long long int*)argp;
+            }
+            argp += 4;
+            break;
     }
 
-    // convert number to ASCII
     do
     {
-        uint32_t rem = number % radix;
-        number = 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
+}
diff --git a/src/bootloader/stage2/stdio.h b/src/bootloader/stage2/stdio.h
index 0735127..b76e0dc 100644
--- a/src/bootloader/stage2/stdio.h
+++ b/src/bootloader/stage2/stdio.h
@@ -2,4 +2,5 @@
 
 void putc(char c);
 void puts(const char* str);
-void _cdecl printf(const char *fmt, ...);
\ No newline at end of file
+void puts_f(const char far* str);
+void _cdecl printf(const char* fmt, ...);
diff --git a/src/bootloader/stage2/x86.asm b/src/bootloader/stage2/x86.asm
index 706f4fe..3bab9da 100644
--- a/src/bootloader/stage2/x86.asm
+++ b/src/bootloader/stage2/x86.asm
@@ -16,7 +16,7 @@ _x86_Video_WriteCharTeletype:
     int 10h
 
     pop bx
-    
+
     mov sp, bp
     pop bp
 
@@ -24,4 +24,25 @@ _x86_Video_WriteCharTeletype:
 
 global _x86_div64_32
 
-_x86_div64_32:
\ No newline at end of file
+_x86_div64_32:
+    push bp
+    mov bp, sp
+
+    push bx
+    mov eax, [bp + 4]
+    mov ecx, [bp + 12]
+    xor edx, edx
+    div ecx
+    mov bx, [bp + 16]
+    mov [bx + 4], eax
+    mov eax, [bp + 4]
+    div ecx
+    mov [bx], eax
+    mov bx, [bp + 18]
+    mov [bx], edx
+    pop bx
+
+    mov sp, bp
+    pop bp
+
+    ret
diff --git a/src/bootloader/stage2/x86.h b/src/bootloader/stage2/x86.h
index 8a057dc..06622db 100644
--- a/src/bootloader/stage2/x86.h
+++ b/src/bootloader/stage2/x86.h
@@ -1,5 +1,6 @@
 #pragma once
 #include "stdint.h"
 
+void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t* quotientOut, uint32_t* remainderOut);
+
 void _cdecl x86_Video_WriteCharTeletype(char c, uint8_t page);
-void _cdecl x86_div64_32(uint64_t dividend, uint32_t divisor, uint64_t *quotientOut, uint64_t *remainderOut);
\ No newline at end of file