int x = 0; int y = 0; int lc = 0; int VGA_WIDTH = 24; char *line = 0x00; void clear() { char *mem = (char*)0xb8000; int i = 0; while (i < 4096) { mem[i++] = 0; } } /* We will use this later on for reading from the I/O ports to get data * from devices such as the keyboard. We are using what is called * 'inline assembly' in these routines to actually do the work */ unsigned char inportb (unsigned short _port) { unsigned char rv; __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); return rv; } /* We will use this to write to I/O ports to send bytes to devices. This * will be used in the next tutorial for changing the textmode cursor * position. Again, we use some inline assembly for the stuff that simply * cannot be done in C */ void outportb (unsigned short _port, unsigned char _data) { __asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); } // This is the x86's VGA textmode buffer. To display text, we write data to this memory location volatile uint16_t* vga_buffer = (uint16_t*)0xB8000; // By default, the VGA textmode buffer has a size of 80x25 characters const int VGA_COLS = 80; const int VGA_ROWS = 25; // We start displaying text in the top-left of the screen (column = 0, row = 0) int term_col = 0; int term_row = 0; uint8_t term_color = 0x0F; // Black background, White foreground // This function initiates the terminal by clearing it void term_init() { // Clear the textmode buffer for (int col = 0; col < VGA_COLS; col ++) { for (int row = 0; row < VGA_ROWS; row ++) { // The VGA textmode buffer has size (VGA_COLS * VGA_ROWS). // Given this, we find an index into the buffer for our character const size_t index = (VGA_COLS * row) + col; // Entries in the VGA buffer take the binary form BBBBFFFFCCCCCCCC, where: // - B is the background color // - F is the foreground color // - C is the ASCII character vga_buffer[index] = ((uint16_t)term_color << 8) | ' '; // Set the character to blank (a space character) } } } // This function places a single character onto the screen void printc(char c) { // Remember - we don't want to display ALL characters! switch (c) { case '\n': // Newline characters should return the column to 0, and increment the row { term_col = 0; term_row ++; break; } default: // Normal characters just get displayed and then increment the column { const size_t index = (VGA_COLS * term_row) + term_col; // Like before, calculate the buffer index vga_buffer[index] = ((uint16_t)term_color << 8) | c; term_col ++; break; } } // What happens if we get past the last column? We need to reset the column to 0, and increment the row to get to a new line if (term_col >= VGA_COLS) { term_col = 0; term_row ++; } // What happens if we get past the last row? We need to reset both column and row to 0 in order to loop back to the top of the screen if (term_row >= VGA_ROWS) { term_col = 0; term_row = 0; } } // This function prints an entire string onto the screen void print(const char* str) { if (str == 0x07) { beep(); } else { for (size_t i = 0; str[i] != '\0'; i ++) // Keep placing characters until we hit the null-terminating character ('\0') printc(str[i]); } } char int2str(int num) { //convert int to string without common libraries char str[10]; int i = 0; while (num > 0) { str[i] = num % 10 + '0'; num /= 10; i++; } str[i] = '\0'; char *p = str; while (*p != '\0') { p++; } p--; char c = *p; *p = '\0'; return c; } void printint(int num) { char str = int2str(num); //Make number a string. print(str); //print it. } //DO NOT USE void vgaprint(char *text, int color) { lc = color; char *mem = (char*)0xb8000; if (y == 23) { clear(lc); y = 0; } while (*text != 0) { if (x > 78) { int i = 0; while (i < x){ mem[i++] = 0; } x = 0; y = y + 1; } x = x + 1; if (*text == "\n") { int i = 0; while (i < x) { mem[i++] = 0; } x = 0; y = y + 1; } else { *mem++ = *text++; *mem++ = color; } int i = 0; while (i < x) { mem[i++] = 0; } x = 0; y = y + 1; } } int lastVGATextColor() { return lc; } void setTermColor(uint8_t color) { term_color = color; } uint8_t termColor() { return term_color; } //create malloc function without standard libs char malloc(int size) { char *mem = (char*)0xb8000; int i = 0; while (i < size) { mem[i++] = 0; } return (char)mem; } //create free function without standard libs void free(char *mem) { int i = 0; while (mem[i] != 0) { mem[i++] = 0; } } void basickeys() { register char *ptr asm("ax");; //pointer var //do something while(*ptr != '\0') { *line = *ptr; print(ptr); //try to print what's in memory ptr++; //add 1 to ptr } }