diff --git a/Rsconscript b/Rsconscript index 0dfea37..78b76b2 100644 --- a/Rsconscript +++ b/Rsconscript @@ -75,7 +75,7 @@ hel_env = env "hel", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env| env.add_builder(Image) env["sources"] = glob("src/hel/**/*.d") env["sources"] += glob("uefi-d/source/**/*.d") - env["DFLAGS"] += %w[-mtriple=x86_64-unknown-windows-coff --betterC -release -O3] + env["DFLAGS"] += %w[-mtriple=x86_64-unknown-windows-coff --betterC -release -O3 --wi] env["D_IMPORT_PATH"] += %w[src/hel uefi-d/source] env["LD"] = "x86_64-w64-mingw32-gcc" env["LDFLAGS"] += %w[-nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -Wl,-Map,${_TARGET}.map] diff --git a/src/hel/hel.d b/src/hel/hel.d index 9a6b48d..4199ea3 100644 --- a/src/hel/hel.d +++ b/src/hel/hel.d @@ -10,6 +10,7 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st) st.ConOut.ClearScreen(st.ConOut); writeln("HOS EFI loader"); + writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor); writeln("Press any key..."); st.ConIn.Reset(st.ConIn, FALSE); diff --git a/src/hel/output.d b/src/hel/output.d index fa4e304..96506f4 100644 --- a/src/hel/output.d +++ b/src/hel/output.d @@ -1,21 +1,122 @@ import uefi; import hel; +import core.stdc.stdarg; -void write(string s) +private size_t format_hex(CHAR16 * s, ulong v, bool ptr) +{ + string hex_chars = "0123456789ABCDEF"; + bool print = ptr; + size_t si = 0u; + for (size_t i = 0u; i < 16u; i++) + { + if (ptr && (i == 8u)) + { + s[si++] = '_'; + } + ulong n = (v >> (60u - 4u * i)) & 0xFu; + if (n != 0u) + { + print = true; + } + if (print || (i == 15u)) + { + s[si++] = hex_chars[n]; + } + } + return si; +} + +private size_t format_dec(CHAR16 * s, ulong v) +{ + string dec_chars = "0123456789"; + bool print; + char[20] buf; + size_t buf_i; + while ((buf_i == 0u) || (v != 0u)) + { + ulong n = v % 10u; + buf[buf_i++] = dec_chars[n]; + v /= 10u; + } + for (size_t si = 0u; si < buf_i; si++) + { + s[si] = buf[buf_i - si - 1u]; + } + return buf_i; +} + +void write(string s, va_list args) { __gshared static CHAR16[256] s16; size_t i = 0u; - while (i < s.length) + bool escape = false; + foreach (char c; s) { - s16[i] = s[i]; - i++; + if (escape) + { + if (c == '%') + { + s16[i++] = '%'; + } + else if (c == 'x') + { + ulong v; + va_arg(args, v); + i += format_hex(&s16[i], v, false); + } + else if (c == 'p') + { + ulong v; + va_arg(args, v); + i += format_hex(&s16[i], v, true); + } + else if (c == 'S') + { + const(CHAR16) * s2; + va_arg(args, s2); + for (size_t s2_i = 0u; s2[s2_i] != 0; s2_i++) + { + s16[i++] = s2[s2_i]; + } + } + else if (c == 'u') + { + ulong v; + va_arg(args, v); + i += format_dec(&s16[i], v); + } + else + { + s16[i++] = c; + } + escape = false; + } + else if (c == '%') + { + escape = true; + } + else + { + s16[i++] = c; + } } s16[i++] = 0u; g_st.ConOut.OutputString(g_st.ConOut, &s16[0]); } -void writeln(string s) +extern (C) void write(string s, ...) { - write(s); - write("\r\n"); + va_list args; + va_start(args, s); + write(s, args); + va_end(args); +} + +extern (C) void writeln(string s, ...) +{ + va_list args; + va_start(args, s); + write(s, args); + write("\r\n", args); + va_end(args); }