#include #include #include #include #include byte default_background, default_foreground; char hex[] = "0123456789ABCDEF"; const static char base_chars[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; int abs(int x) { return (x>0) ? (x) : (x*-1); } void graphics_init() { // Detect if color/monochrome screen char c = (*(volatile unsigned short*)0x410)&0x30; if (c==0x30) TextVideoRam = (byte *)0xb0000; else TextVideoRam = (byte *)0xb8000; // Reset cursor, use 80x25 text video mode current_mode_width = 80; current_mode_height = 25; cursor_x = cursor_y = 0; } // Change cursor position void text_mode_cursor(int x, int y) { unsigned temp = y*current_mode_width + x; outportb (0x3D4, 14); outportb (0x3D5, temp >> 8); outportb (0x3D4, 15); outportb (0x3D5, temp); } // Set the default colors; max is 0x0F void set_default_colors(byte back, byte fore) { if (back < 0x10) default_background = back; if (fore < 0x10) default_foreground = fore; } // Clear screen, and set font to default font void clrscr() { byte font = default_foreground | (default_background<<4); int i = 0; for (i = 0; i < current_mode_width*current_mode_height; i++) { TextVideoRam[2*i] = 0; TextVideoRam[2*i+1] = font; } cursor_x = 0; cursor_y = 0; } void scroll(int n) { memcpy(TextVideoRam, TextVideoRam+(current_mode_width*n*2), 2*current_mode_width*(current_mode_height - n)); byte blank = default_foreground | (default_background<<4); int i; for (i = current_mode_width*(current_mode_height-n); i < current_mode_width*current_mode_height; i++){ TextVideoRam[2*i] = 0; TextVideoRam[2*i+1] = blank; } } void prev_line() { cursor_x = 79; if (--cursor_y < 0) { cursor_y = 0; cursor_x=0; } } void next_line() { cursor_x = 0; if (++cursor_y >=25) { cursor_y = 24; scroll(1); } } // Put character on screen in specified position; can use different font colors void putc_pos_font(int x, int y, char c, byte back, byte fore) { TextVideoRam[2*(y*current_mode_width+x)] = c; TextVideoRam[2*(y*current_mode_width+x)+1] = fore|(back<<4); } // Put character on screen in specified position; use default font colors void putc_pos(int x, int y, char c) { TextVideoRam[2*(y*current_mode_width+x)] = c; } // Put character on screen in the current cursor position; different font colors void putc_font(char c, byte back, byte fore) { if (cursor_x >= current_mode_width) next_line(); if (c == '\n') {next_line(); return;}; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)+1] = fore|(back<<4); cursor_x++; } // Put character on screen in the current cursor position; default font colors void putc(char c) { if (cursor_x >= current_mode_width) next_line(); if (c == '\n') {next_line(); return;}; if (c == '\r') {cursor_x = 0; return; }; TextVideoRam[2*(cursor_y*current_mode_width+cursor_x)] = c; cursor_x++; } // Unsigned INT to ASCII void uitoa (unsigned int value, char *string, int radix) { if (radix == 1 || radix>36) return; // Calculate how much space needed for number int len, temp = abs(value); for (len = 0; temp > 0; len++) temp/=radix; if (len == 0) len = 1; string[len] = 0; for (len--; len >=0; len-- ) { string[len] = base_chars[value%radix]; value/=radix; } } // Signed INT to ASCII void itoa (int value, char *string, unsigned int radix) { if (radix < 2 || radix>36) return; // Calculate how much space needed for number int len, temp = abs(value); for (len = 0; temp > 0; len++) temp/=radix; if (len == 0) len = 1; //Add a space for '-' if (value<0) { len++; string[0] = '-'; value = abs(value); } string[len] = 0; for (len--; len >0; len-- ) { string[len] = base_chars[value%radix]; value/=radix; } } // Put string on screen in specified position; can use different font colors void puts_pos_font(int x, int y, const char *str, byte back, byte fore) { int i; for (i = 0; str[i] != 0; i++) putc_pos_font(x+i, y, str[i], back, fore); } // Put string on screen in specified position; use default font colors void puts_pos(int x, int y, const char *str) { int i; for (i = 0; str[i] != 0; i++) putc_pos(x+i, y, str[i]); } void puts(const char *str) { int i; for (i = 0; str[i] != 0; i++) putc(str[i]); } void puts_font(const char *str, byte back, byte fore) { int i; for (i = 0; str[i] != 0; i++) putc_font(str[i], back, fore); } void put_hex(unsigned int alpha) { char nr[9]; int i; for (i = 7; i >= 0; i--) { nr[i] = hex[alpha%16]; alpha /= 16; } nr[8] = 0; puts(nr); } void put_hex_pos(int x, int y, unsigned int alpha) { char nr[9]; int i; for (i = 7; i >= 0; i--) { nr[i] = hex[alpha%16]; alpha /= 16; } nr[8] = 0; puts_pos(x,y,nr); } void put_bin (int x, int y, byte xz) { int i; char arr[9] = {0,0,0,0,0,0,0,0,0}; for(i=7; i>=0; i--) { arr[i] = (xz%2) + '0'; xz/=2; } puts_pos (x, y, arr); } int printf(const char* str, ...) { if (!str) return 0; va_list args; va_start (args, str); size_t i, len = strlen(str); for (i = 0; i < len; i++) switch (str[i]) { case '%': switch (str[i+1]) { // Character case 'c': {char c = va_arg (args, char); putc(c); i++; break;} // String case 's': {int* c = (int*) va_arg (args, char*); puts((const char*)c); i++; break;} // Integers case 'd': case 'i': {int c = va_arg(args, int); char temp[32]; itoa(c, temp, 10); puts(temp); i++; break;} // Integers - hex case 'X': case 'x': {int c = va_arg(args, int); char temp[32]; uitoa(c, temp, 16); puts(temp); i++; break;} // Integers - unsigned case 'u': { int c = va_arg(args, unsigned int); char temp[32]; uitoa(c, temp, 10); puts(temp); i++; break; } default: va_end(args); return 1; }; break; default: putc(str[i]); break; } va_end(args); return i; }