mirror of
https://github.com/limine-bootloader/limine
synced 2025-01-21 03:52:04 +03:00
Added print
This commit is contained in:
parent
3645ec0b75
commit
77572b0df4
@ -68,7 +68,7 @@ dw 0xaa55
|
||||
|
||||
mov ax, 2
|
||||
mov ebx, 0x8000
|
||||
mov cx, 6
|
||||
mov cx, 14
|
||||
call read_sectors
|
||||
|
||||
jc err
|
||||
|
171
lib/print.c
Normal file
171
lib/print.c
Normal file
@ -0,0 +1,171 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <lib/print.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
|
||||
static const char *base_digits = "0123456789abcdef";
|
||||
|
||||
#define PRINT_BUF_MAX 512
|
||||
|
||||
static void prn_str(char *print_buf, size_t *print_buf_i, const char *string) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; string[i]; i++) {
|
||||
if (*print_buf_i == (PRINT_BUF_MAX - 1))
|
||||
break;
|
||||
print_buf[(*print_buf_i)++] = string[i];
|
||||
}
|
||||
|
||||
print_buf[*print_buf_i] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void prn_nstr(char *print_buf, size_t *print_buf_i, const char *string, size_t len) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (*print_buf_i == (PRINT_BUF_MAX - 1))
|
||||
break;
|
||||
print_buf[(*print_buf_i)++] = string[i];
|
||||
}
|
||||
|
||||
print_buf[*print_buf_i] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void prn_char(char *print_buf, size_t *print_buf_i, char c) {
|
||||
if (*print_buf_i < (PRINT_BUF_MAX - 1)) {
|
||||
print_buf[(*print_buf_i)++] = c;
|
||||
}
|
||||
|
||||
print_buf[*print_buf_i] = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void prn_i(char *print_buf, size_t *print_buf_i, int32_t x) {
|
||||
int i;
|
||||
char buf[12] = {0};
|
||||
|
||||
if (!x) {
|
||||
prn_char(print_buf, print_buf_i, '0');
|
||||
return;
|
||||
}
|
||||
|
||||
int sign = x < 0;
|
||||
if (sign) x = -x;
|
||||
|
||||
for (i = 10; x; i--) {
|
||||
buf[i] = (x % 10) + 0x30;
|
||||
x = x / 10;
|
||||
}
|
||||
if (sign)
|
||||
buf[i] = '-';
|
||||
else
|
||||
i++;
|
||||
|
||||
prn_str(print_buf, print_buf_i, buf + i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void prn_ui(char *print_buf, size_t *print_buf_i, uint32_t x) {
|
||||
int i;
|
||||
char buf[11] = {0};
|
||||
|
||||
if (!x) {
|
||||
prn_char(print_buf, print_buf_i, '0');
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 9; x; i--) {
|
||||
buf[i] = (x % 10) + 0x30;
|
||||
x = x / 10;
|
||||
}
|
||||
|
||||
i++;
|
||||
prn_str(print_buf, print_buf_i, buf + i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void prn_x(char *print_buf, size_t *print_buf_i, uint32_t x) {
|
||||
int i;
|
||||
char buf[9] = {0};
|
||||
|
||||
if (!x) {
|
||||
prn_str(print_buf, print_buf_i, "0x0");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 7; x; i--) {
|
||||
buf[i] = base_digits[(x % 16)];
|
||||
x = x / 16;
|
||||
}
|
||||
|
||||
i++;
|
||||
prn_str(print_buf, print_buf_i, "0x");
|
||||
prn_str(print_buf, print_buf_i, buf + i);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void print(const char *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, fmt);
|
||||
|
||||
char print_buf[PRINT_BUF_MAX];
|
||||
size_t print_buf_i = 0;
|
||||
|
||||
for (;;) {
|
||||
while (*fmt && *fmt != '%')
|
||||
prn_char(print_buf, &print_buf_i, *fmt++);
|
||||
|
||||
if (!*fmt++)
|
||||
goto out;
|
||||
|
||||
switch (*fmt++) {
|
||||
case 's': {
|
||||
char *str = (char *)va_arg(args, const char *);
|
||||
if (!str)
|
||||
prn_str(print_buf, &print_buf_i, "(null)");
|
||||
else
|
||||
prn_str(print_buf, &print_buf_i, str); }
|
||||
break;
|
||||
case 'S': {
|
||||
char *str = (char *)va_arg(args, const char *);
|
||||
size_t str_len = va_arg(args, size_t);
|
||||
if (!str)
|
||||
prn_str(print_buf, &print_buf_i, "(null)");
|
||||
else
|
||||
prn_nstr(print_buf, &print_buf_i, str, str_len); }
|
||||
break;
|
||||
case 'd':
|
||||
prn_i(print_buf, &print_buf_i, va_arg(args, int32_t));
|
||||
break;
|
||||
case 'u':
|
||||
prn_ui(print_buf, &print_buf_i, va_arg(args, uint32_t));
|
||||
break;
|
||||
case 'x':
|
||||
prn_x(print_buf, &print_buf_i, va_arg(args, uint32_t));
|
||||
break;
|
||||
case 'c': {
|
||||
char c = (char)va_arg(args, int);
|
||||
prn_char(print_buf, &print_buf_i, c); }
|
||||
break;
|
||||
default:
|
||||
prn_char(print_buf, &print_buf_i, '?');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
va_end(args);
|
||||
text_write(print_buf, print_buf_i);
|
||||
|
||||
return;
|
||||
}
|
6
lib/print.h
Normal file
6
lib/print.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __PRINT_H__
|
||||
#define __PRINT_H__
|
||||
|
||||
void print(const char *, ...);
|
||||
|
||||
#endif
|
@ -14,7 +14,7 @@ SECTIONS
|
||||
.data : {
|
||||
KEEP(*(.data*))
|
||||
KEEP(*(.bss*))
|
||||
. += 3072 - (. - bootsect_begin);
|
||||
. += 7168 - (. - bootsect_begin);
|
||||
}
|
||||
|
||||
}
|
||||
|
5
main.c
5
main.c
@ -7,10 +7,13 @@ asm (
|
||||
|
||||
#include <drivers/vga_textmode.h>
|
||||
#include <lib/real.h>
|
||||
#include <lib/print.h>
|
||||
|
||||
void main(int boot_drive) {
|
||||
init_vga_textmode();
|
||||
text_write("qLoader 2\n\n", 11);
|
||||
print("qLoader 2\n\n");
|
||||
print("=> Boot drive: %x\n", boot_drive);
|
||||
print("\n");
|
||||
for (;;) {
|
||||
struct rm_regs r = {0};
|
||||
rm_int(0x16, &r, &r); // Real mode interrupt 16h
|
||||
|
Loading…
Reference in New Issue
Block a user