14 #define make_color(fg, bg) (fg | bg << 4)
15 #define make_vga(ch, color) ((uint16_t)(ch & 0xff | color << 8))
20 static struct virtual_console {
26 struct terminal terminal = { 0 };
30 uint16_t blank = make_vga(' ', terminal.color);
31 for (i=0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
32 terminal.vmem[i] = blank;
36 static void scroll(int lines) {
37 uint16_t *base, *offset;
42 offset = base + VGA_WIDTH * lines;
43 memmove(base, offset, (VGA_WIDTH * VGA_HEIGHT - lines) * 2);
45 offset = base + (VGA_WIDTH * VGA_HEIGHT - lines);
46 blank = make_vga(' ', terminal.color);
47 for (i=0; i < VGA_WIDTH * lines; i++) {
52 static void putentryat(int c, uint8_t color, size_t x, size_t y) {
53 size_t index = y * VGA_WIDTH + x;
54 terminal.vmem[index] = make_vga(c, color);
57 static void putchar(int c) {
58 if (terminal.escape) {
69 if (++terminal.row == VGA_HEIGHT) {
70 terminal.row = VGA_HEIGHT-1;
78 putentryat(c, terminal.color, terminal.column, terminal.row);
83 if (terminal.column == VGA_WIDTH) {
85 if (++terminal.row == VGA_HEIGHT) {
86 terminal.row = VGA_HEIGHT-1;
92 static void setcursor(int row, int col) {
93 uint16_t position = (row*VGA_WIDTH) + col;
95 /* cursor low port to vga index register */
96 outport8(0x3D4, 0x0F);
97 outport8(0x3D5, (unsigned char)(position&0xFF));
98 /* cursor high port to vga index register */
99 outport8(0x3D4, 0x0E);
100 outport8(0x3D5, (unsigned char )((position>>8)&0xFF));
103 static void updcursor() {
104 setcursor(terminal.row, terminal.column);
107 static void writestring(const char *data) {
116 void terminal_initialize() {
117 terminal.putchar = putchar;
118 terminal.clear = clear;
119 terminal.scroll = scroll;
120 terminal.writestring = writestring;
122 terminal.vmem = (uint16_t *) (0xb8000 + _asm_physmap);
123 terminal.update_cursor = updcursor;
129 terminal.color = make_color(VGA_LIGHT_GREY, VGA_BLACK);