Поговорим на языке высокого уровня (start.c)
Вот теперь мы вернулись к тому с чего начинали рассказ. Почти вернулись, потому что printf() теперь надо делать вручную. поскольку готовых прерываний уже нет, то будем использовать прямую запись в видеопамять. Для любопытных - почти весь код этой части , с незначительными изменениями, повзаимствован из части ядра Linux, осуществляющей распаковку (/arch/i386/boot/compressed/*). Для сборки вам потребуется дополнительно определить такие макросы как inb(), outb(), inb_p(), outb_p(). Готовые определения проще всего одолжить из любой версии Linux.
Теперь, дабы не путаться со встроенными в glibc функциями, отменим их определение #undef memcpy
Зададим несколько своих static void puts(const char *); static char *vidmem = (char *)0xb8000; /*адрес видеопамати*/ static int vidport; /*видеопорт*/ static int lines, cols; /*количество линий и строк на экран*/ static int curr_x,curr_y; /*текущее положение курсора */
И начнем, наконец, писать код на языке высокого уровня... правда с небольшими ассемблерными вставками.
/*функция перевода курсора в положение (x,y). Работа ведется через ввод/вывод в видеопорт*/ void gotoxy(int x, int y) { int pos; pos = (x + cols * y) * 2; outb_p(14, vidport); outb_p(0xff & (pos >> 9), vidport+1); outb_p(15, vidport); outb_p(0xff & (pos >> 1), vidport+1); }
/*функция прокручивания экрана. Работает, используя прямую запись в видеопамять*/ static void scroll() { int i; memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) vidmem[i] = ' '; }
/*функция вывода строки на экран*/ static void puts(const char *s) { int x,y; char c; x = curr_x; y = curr_y; while ( ( c = *s++ ) != '\0' ) { if ( c == '\n' ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } else { vidmem [ ( x + cols * y ) * 2 ] = c; if ( ++x >= cols ) { x = 0; if ( ++y >= lines ) { scroll(); y--; } } } } gotoxy(x,y); }
/*функция копирования из одной области памяти в другую. Заместитель стандартной функции glibc */ void* memcpy(void* __dest, __const void* __src, unsigned int __n) { int i; char *d = (char *)__dest, *s = (char *)__src; for (i=0;i<__n;i++) d[i] = s[i]; }
/*функция издающая долгий и протяжных звук.