#include #include int posX, posY, kprintf_res; char *video = (char*)0xB8000; int color = 0x07; char ansi_buf[5]; int strcmp(const char*a,const char*b) { while(*a == *b && *a) { a++; ++b; } return *(const unsigned char*)a - *(const unsigned char*)b; } bool cmdline_debug; void init_cmdline() { char *cmd_line = (char*)mbi->mbs_cmdline; kprintf("%s\n", cmd_line); while(*cmd_line != 0) { if(*cmd_line == 'd' || *cmd_line == 'D') cmdline_debug = true; cmd_line++; } } void removecursor() { outb(0x3D4,14); outb(0x3D5,0x07); outb(0x3D4,15); outb(0x3D5,0xD0); } void move_cursor(uint8_t col,uint8_t row) { uint16_t tmp; tmp = row*80+col; outb(0x3D4,14); outb(0x3D5,tmp>>8); outb(0x3D4,15); outb(0x3D5,tmp); } void kputc(char c) { if(c == 0) return; if(cmdline_debug) { if(c == '\n') write_com(0x3F8, '\r'); write_com(0x3F8, c); } if(!vesa_active) { if ((c == '\n') || (posX > 79)) { posX = 0; posY++; } if (c == '\n') { move_cursor(posX, posY); return; } if (posY > 24) { int i; for (i = 0; i < 2 * 24 * 80; i++) { video[i] = video[i + 160]; } for (; i < 2 * 25 * 80; i++) { video[i] = 0; } posY--; } video[2 * (posY * 80 + posX)] = c; video[2 * (posY * 80 + posX) + 1] = color; posX++; kprintf_res++; move_cursor(posX, posY); } else { if ((c == '\n') || (posX > 79)) { posX = 0; posY++; return; } print_char(c); posX++; kprintf_res++; } } void kputs(const char* s) { while (*s) { kputc(*s++); } } void kputn(unsigned long x, int base) { char buf[65]; const char* digits = "0123456789abcdefghijklmnopqrstuvwxyz"; char* p; if (base > 36) { return; } p = buf + 64; *p = '\0'; do { *--p = digits[x % base]; x /= base; } while (x); kputs(p); } void ansi_parse() { char *c = ansi_buf; if(*c == '\033') { c++; char buffer[4]; buffer[0] = *c; c++; buffer[1] = *c; c++; buffer[2] = *c; c++; buffer[3] = *c; c++; int tempB = 0x0; switch(buffer[2]) { case '0': tempB = 0x0; break; case '1': tempB = 0x10; break; case '2': tempB = 0x20; break; case '3': tempB = 0x30; break; case '4': tempB = 0x40; break; case '5': tempB = 0x50; break; case '6': tempB = 0x60; break; case '7': tempB = 0x70; break; case '8': tempB = 0x80; break; case '9': tempB = 0x90; break; case 'a': case 'A': tempB = 0xA0; break; case 'b': case 'B': tempB = 0xB0; break; case 'c': case 'C': tempB = 0xC0; break; case 'd': case 'D': tempB = 0xD0; break; case 'e': case 'E': tempB = 0xE0; break; case 'f': case 'F': tempB = 0xF0; break; } int tempF = 0x7; switch(buffer[3]) { case '0': tempF = 0x0; break; case '1': tempF = 0x1; break; case '2': tempF = 0x2; break; case '3': tempF = 0x3; break; case '4': tempF = 0x4; break; case '5': tempF = 0x5; break; case '6': tempF = 0x6; break; case '7': tempF = 0x7; break; case '8': tempF = 0x8; break; case '9': tempF = 0x9; break; case 'a': case 'A': tempF = 0xA; break; case 'b': case 'B': tempF = 0xB; break; case 'c': case 'C': tempF = 0xC; break; case 'd': case 'D': tempF = 0xD; break; case 'e': case 'E': tempF = 0xE; break; case 'f': case 'F': tempF = 0xF; break; } color = tempB + tempF; } } int kprintf(const char* fmt, ...) { va_list ap; const char* s; unsigned long n; va_start(ap, fmt); int kprintf_res = 0; int c; while (*fmt) { if (*fmt == 0x1b) { kprintf("ANSI SEQUENZ\n"); int i; for(i = 0; i < 5; i++) { ansi_buf[i] = *fmt+i; } ansi_parse(); } else if (*fmt == '%') { fmt++; switch (*fmt) { case 's': s = va_arg(ap, char*); kputs(s); break; case 'd': case 'u': n = va_arg(ap, unsigned long int); kputn(n, 10); break; case 'x': case 'p': n = va_arg(ap, unsigned long int); kputn(n, 16); break; case '%': kputc('%'); break; case 'c': c = va_arg(ap, int); kputc(c); break; case '\0': goto out; default: kputc('%'); kputc(*fmt); break; } } else { kputc(*fmt); } fmt++; } out: va_end(ap); return kprintf_res; } void clear_screen() { int x, y; posX = 0; posY = 0; for(y = 0; y < 25; y++) { for(x = 0; x < 80; x++) { kputc(' '); } } posX = 0; posY = 0; }