-
Notifications
You must be signed in to change notification settings - Fork 0
/
framebuffer.c
66 lines (54 loc) · 1.54 KB
/
framebuffer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "framebuffer.h"
/* Starting address for the framebuffer memory-mapped IO */
char *fb = (char *) 0xC00B8000;
unsigned short fb_curr_pos = 0x00000000;
void advance_cursor();
int fb_write(char *buf) {
unsigned int i = 0;
while (buf[i] != 0) {
switch(buf[i]) {
case '\n':
fb_move_cursor(fb_curr_pos + FB_COLS - fb_curr_pos % FB_COLS);
break;
default:
fb_write_cell(fb_curr_pos * 2, buf[i], (unsigned char) 15, (unsigned char) 0);
advance_cursor();
break;
}
if (fb_curr_pos >= FB_ROWS * FB_COLS) {
fb_scroll_by(1);
}
i++;
}
return 0;
}
void fb_backspace() {
if (fb_curr_pos <= 0) return;
/* TODO: Handle backspace across newline */
fb_move_cursor(fb_curr_pos - 1);
fb_write_cell(fb_curr_pos * 2, ' ', (unsigned char) 15, (unsigned char) 0);
}
void fb_scroll_by(unsigned int lines) {
unsigned int i;
for (i = 0; i < (FB_ROWS - lines) * FB_COLS * 2; i++) {
fb[i] = fb[i + FB_COLS * 2];
}
for (i = i; i < FB_ROWS * FB_COLS * 2; i++) {
fb[i] = 0;
}
fb_move_cursor(fb_curr_pos - FB_COLS * lines);
}
void fb_move_cursor(unsigned short pos) {
outb(FB_COMMAND_PORT, FB_HIGH_BYTE_COMMAND);
outb(FB_DATA_PORT, ((pos >> 8) & 0x00FF));
outb(FB_COMMAND_PORT, FB_LOW_BYTE_COMMAND);
outb(FB_DATA_PORT, pos & 0x00FF);
fb_curr_pos = pos;
}
void fb_write_cell(unsigned int i, char c, unsigned char fg, unsigned char bg) {
fb[i] = c;
fb[i + 1] = ((bg & 0x0F) << 4) | (fg & 0x0F);
}
void advance_cursor() {
fb_move_cursor(fb_curr_pos + 1);
}