Here it is, mind you I'm still working on it so it probably has a few bugs. Also I have some ideas I want to implement like adding field width and pad so that you can use this
Code: Select all
typedef char *va_list;
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
#define va_start(ap, v) (ap = (va_list) &v + _INTSIZEOF(v))
#define va_arg(ap, t) (*(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define va_end(ap) (ap = (va_list) 0)
typedef unsigned int dword;
typedef unsigned short word;
typedef unsigned char byte;
#define NULL ((void *) 0)
#define true 1
#define false 0
void memcpy(void *dest, const void *src, int n) {
//asm rep movbs ? ##########################################
int i;
for (i = 0; i < n; i++)
((byte *)dest)[i] = ((byte *)src)[i];
}
void *memset(void *s, int c, int n) {
//asm rep movbs ? ##########################################
int *ip = (int *) s;
int i;
for (i = 0; i < n; i++)
*ip++ = c;
}
void strcpy (char *dest, const char *src) {
while (*src)
*dest++ = *src++;
*dest = 0;
}
int strcmp (const char *a, const char *b) {
while (*a && *b && *a == *b) {
a++;
b++;
}
if (*a == 0 && *b == 0)
return 0;
else if (*a < *b)
return -1;
else
return 1;
}
int strlen (const char *str) {
int size = 0;
while (*str++)
size++;
return size;
}
void outb (word port, byte value) {
asm volatile ("outb %1, %0" : : "dN" (port), "a" (value));
}
char *video_mem = (char *)0xb8000;
word cursor = 0;
void scroll () {
memcpy(video_mem, video_mem + 160, 4000 - 160);
memset(video_mem + 4000 - 160, 0x07200720, 40);
cursor -= 160;
}
#define BLACK 0x0
#define BLUE 0x1
#define GREEN 0x2
#define CYAN 0x3
#define RED 0x4
#define MAGENTA 0x5
#define BROWN 0x6
#define LIGHT_GREY 0x7
#define DARK_GREY 0x8
#define LIGHT_BLUE 0x9
#define LIGHT_GREEN 0xA
#define LIGHT_CYAN 0xB
#define LIGHT_RED 0xC
#define LIGHT_MAGNETA 0xD
#define LIGHT_BROWN 0xE
#define WHITE 0xF
byte foreground = LIGHT_GREY;
byte background = BLACK;
void print_char (char c) {
if (cursor >= 4000)
scroll();
if (c == '\n') {
cursor += 160;
cursor = cursor - (cursor % 160);
}
else {
video_mem[cursor++] = c;
video_mem[cursor++] = foreground | (background << 4);
}
outb(0x3d4, 14);
outb(0x3d5, cursor >> 9);
outb(0x3d4, 15);
outb(0x3d5, cursor >> 1);
}
void print_string (char *str) {
char *sp;
for (sp = str; *sp != 0; sp++)
print_char(*sp);
}
void clear_screen () {
int i;
for (i = 0; i < 2000; i++)
print_char(' ');
cursor = 0;
}
void get_tag_name (char *str, char *buffer) {
str++;
for (; *str != ' ' && *str != '>'; str++, buffer++)
*buffer = *str;
*buffer = 0;
}
char *get_attrib (char *str, char *name, char *value) {
if (*str == '>')
return NULL;
while (*str != '=')
*name++ = *str++;
*name = 0;
str++;
while (*str != ',' && *str != '>')
*value++ = *str++;
*value = 0;
if (*str == ',')
return str + 1;
else
return str;
}
void get_attrib_value (char *name, char *str,
char *buffer, char *default_val) {
while (*str++ != ' ')
;
char name_buffer[32];
char value_buffer[32];
while (str = get_attrib(str, name_buffer, value_buffer)) {
if (!strcmp(name_buffer, name)) {
strcpy(buffer, value_buffer);
return;
}
}
strcpy(buffer, default_val);
}
void reverse_string (char *str) {
int start = 0;
int end = strlen(str) - 1;
while (start < end) {
char temp = str[end];
str[end] = str[start];
str[start] = temp;
start++;
end--;
}
}
void int_to_string (dword i, int base, char *buffer) {
int index = 0;
while (i != 0) {
int offset = i % base;
if (offset < 10)
buffer[index++] = offset + '0';
else
buffer[index++] = offset - 10 + 'A';
i /= base;
}
buffer[index] = 0;
reverse_string(buffer);
}
void print_decimal (int num) {
int negative = 0;
if (num < 0) {
negative = 1;
num = -num;
}
char buffer[64];
int_to_string(num, 10, buffer);
if (negative)
print_char('-');
print_string(buffer);
}
void print_hexadecimal (int num) {
char buffer[64];
int_to_string(num, 16, buffer);
print_string("0x");
print_string(buffer);
}
byte get_color (char *name) {
static char *colors[16] =
{ "black", "blue", "green", "cyan",
"red", "magenta", "brown", "light-grey",
"dark-grey", "light-blue", "light-green",
"light-cyan", "light-red", "light-magneta",
"light-brown", "white" };
int i;
for (i = 0; i < 16; i++) {
if (!strcmp(name, colors[i]))
return i;
}
return -1;
}
void print (char *str, ...) {
va_list ap;
va_start(ap, str);
byte saved_fg;
byte saved_bg;
char *ptr;
char tag_name[32];
for (ptr = str; *ptr; ptr++) {
if (*ptr == ':') {
print_char(*(ptr + 1));
ptr+= 1;
}
else if (*ptr == '<') {
get_tag_name(ptr, tag_name);
if (!strcmp(tag_name, "color")) {
saved_fg = foreground;
saved_bg = background;
char attrib_value[32];
get_attrib_value("fg", ptr, attrib_value, "light-grey");
foreground = get_color(attrib_value);
get_attrib_value("bg", ptr, attrib_value, "black");
background = get_color(attrib_value);
}
else if (!strcmp(tag_name, ":color")) {
foreground = saved_fg;
background = saved_bg;
}
else if (!strcmp(tag_name, "dec")) {
print_decimal(va_arg(ap, int));
}
else if (!strcmp(tag_name, "hex")) {
print_hexadecimal(va_arg(ap, int));
}
else if (!strcmp(tag_name, "str")) {
print_string(va_arg(ap, char *));
}
else if (!strcmp(tag_name, "newline") ||
!strcmp(tag_name, "nl")) {
print_char('\n');
}
while (*ptr != '>')
ptr++;
}
else
print_char(*ptr);
}
va_end(ap);
}
int main () {
clear_screen();
print(
"name="
"<color fg=red>"
"<str>"
"<:color>"
", count="
"<color fg=blue>"
"<dec>"
"<:color>"
", pointer="
"<color fg=cyan,bg=red>"
"<hex>"
"<:color><nl>", "felipe", 1234, 0xffffffbc);
return 0;
}