Sure, I'll edit this in a second. The VGA class is mostly the C++ version of James's. I'll release the Vesa and vm86 drivers when I post the next release on OS Development
Code:#include <base/types.h> #include <base/io.h> #include <base/tasks.h> #include <display/base.h> #include <display/vga.h> void vga::init(void) { this->background = 0; this->foreground = 15; this->video_memory = (u16int *)0xB8000; this->cursor_x = 0; this->cursor_y = 0; this->clear(); } void vga::clear(void) { u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F); u16int blank = 0x20 /* space */ | (attributeByte << 8); int i; for (i = 0; i < 80*25; i++) { this->video_memory[i] = blank; } this->cursor_x = 0; this->cursor_y = 0; this->move(); } void vga::putc(char c) { // The background colour is black (0), the foreground is white (15). u8int backColour = this->background; u8int foreColour = this->foreground; // The attribute byte is made up of two nibbles - the lower being the // foreground colour, and the upper the background colour. u8int attributeByte = (backColour << 4) | (foreColour & 0x0F); // The attribute byte is the top 8 bits of the word we have to send to the // VGA board. u16int attribute = attributeByte << 8; u16int *location; // Handle a backspace, by moving the cursor back one space if (c == 0x08 && this->cursor_x) { this->cursor_x--; } // Handle a tab by increasing the cursor's X, but only to a point // where it is divisible by 8. else if (c == 0x09) { this->cursor_x = (this->cursor_x+8) & ~(8-1); } // Handle carriage return else if (c == '\r') { this->cursor_x = 0; } // Handle newline by moving cursor back to left and increasing the row else if (c == '\n') { this->cursor_x = 0; this->cursor_y++; } // Handle any other printable character. else if(c >= ' ') { location = this->video_memory + (this->cursor_y*80 + this->cursor_x); *location = c | attribute; cursor_x++; } // Check if we need to insert a new line because we have reached the end // of the screen. if (this->cursor_x >= 80) { this->cursor_x = 0; this->cursor_y ++; } // Scroll the screen if needed. scroll(); // Move the hardware cursor. this->move(); } void vga::colors(int foreground, int background) { this->foreground = foreground; this->background = background; } void vga::move(void) { u16int cursorLocation = this->cursor_y * 80 + this->cursor_x; outb(0x3D4, 14); // Tell the VGA board we are setting the high cursor byte. outb(0x3D5, cursorLocation >> 8); // Send the high cursor byte. outb(0x3D4, 15); // Tell the VGA board we are setting the low cursor byte. outb(0x3D5, cursorLocation); // Send the low cursor byte. } void vga::scroll(void) { // Get a space character with the default colour attributes. u8int attributeByte = (0 /*black*/ << 4) | (15 /*white*/ & 0x0F); u16int blank = 0x20 /* space */ | (attributeByte << 8); // Row 25 is the end, this means we need to scroll up if(this->cursor_y >= 25) { // Move the current text chunk that makes up the screen // back in the buffer by a line int i; for (i = 0*80; i < 24*80; i++) { this->video_memory[i] = this->video_memory[i+80]; } // The last line should now be blank. Do this by writing // 80 spaces to it. for (i = 24*80; i < 25*80; i++) { this->video_memory[i] = blank; } // The cursor should now be on the last line. this->cursor_y = 24; } } void vga::puts(const char *frm,...) { __builtin_va_list list; __builtin_va_start(list, frm); for(; *frm != '\0'; frm++) { if(*frm == '%') { frm++; if(*frm == 'i') this->putdec(__builtin_va_arg(list,int)); else if(*frm == 'u') this->puthex(__builtin_va_arg(list,int)); else if(*frm == 's') this->_puts(__builtin_va_arg(list, char *)); else if(*frm == 'c') this->putc(__builtin_va_arg(list, int)); else if(*frm == 'y') this->background = __builtin_va_arg(list,int); else if(*frm == 'z') this->foreground = __builtin_va_arg(list,int); else if(*frm == 'x') this->cursor_x = __builtin_va_arg(list,int); else if(*frm == '%') this->putc('%'); } else if(*frm == '\n') this->putc('\n'); else this->putc(*frm); } } void vga::_puts(char *c) { int i = 0; while (c[i]) { this->putc(c[i++]); } } void vga::putdec(u32int n) { if (n == 0) { this->puts("%c",'0'); return; } s32int acc = n; char c[32]; int i = 0; while (acc > 0) { c[i] = '0' + acc%10; acc /= 10; i++; } c[i] = 0; char c2[32]; c2[i--] = 0; int j = 0; while(i >= 0) { c2[i--] = c[j++]; } this->puts("%s",c2); } void vga::puthex(u32int n) { s32int tmp; this->puts("0x"); char noZeroes = 1; int i; for (i = 28; i > 0; i -= 4) { tmp = (n >> i) & 0xF; if (tmp == 0 && noZeroes != 0) { continue; } if (tmp >= 0xA) { noZeroes = 0; this->puts("%c",tmp-0xA+'a' ); } else { noZeroes = 0; this->puts("%c", tmp+'0' ); } } tmp = n & 0xF; if (tmp >= 0xA) { this->puts("%c",tmp-0xA+'a'); } else { this->puts("%c",tmp+'0'); } }


LinkBack URL
About LinkBacks





Reply With Quote






Bookmarks
Algorithms and Data Structures
Java tutorials
Algorithms Forum