]> git.dujemihanovic.xyz Git - nameless-os.git/blob - kernel/arch/x86/tty.c
kernel: Huge refactoring of tty driver
[nameless-os.git] / kernel / arch / x86 / tty.c
1 #include <io.h>
2 #include <tty.h>
3 #include <stdint.h>
4
5 #define VGA_WIDTH 80
6 #define VGA_HEIGHT 25
7
8 static int cursor_x = 0; /* keep track of where cursor is */
9 static int cursor_y = 0;
10 static uint16_t crtc_port;
11
12 static inline uint8_t vga_get_color(const enum vga_color fg, const enum vga_color bg)
13 {
14 return fg&0xf | bg<<4;
15 }
16
17 static inline uint16_t vga_get_char(const enum vga_color fg, const enum vga_color bg, char character)
18 {
19 return character | vga_get_color(fg, bg)<<8;
20 }
21
22 static inline char *vga_get_memory_address(int x, int y)
23 {
24 return (char *) 0xb8000 + (y*VGA_WIDTH + x)*2;
25 }
26
27 static void vga_scroll_up(void)
28 {
29 for (int y=1; y<VGA_HEIGHT; y++) {
30 for (int x = 0; x<VGA_WIDTH; x++) {
31 *vga_get_memory_address(x, y-1) = *vga_get_memory_address(x, y);
32 }
33 }
34
35 for (int x = 0; x<VGA_WIDTH; x++) {
36 *vga_get_memory_address(x, VGA_HEIGHT-1) = vga_get_char(VGA_LIGHT_GRAY, VGA_BLACK, ' ');
37 }
38 cursor_y = VGA_HEIGHT - 1;
39 }
40
41 static void vga_set_cursor(int x, int y)
42 {
43 uint16_t cursor_address = y*VGA_WIDTH + x;
44
45 outb(crtc_port, 0xe);
46 outb(crtc_port+1, cursor_address>>8);
47 outb(crtc_port, 0xf);
48 outb(crtc_port+1, cursor_address);
49 }
50
51 static void vga_screen_clear(void)
52 {
53 for (int y=0; y<VGA_HEIGHT; y++) {
54 for (int x=0; x<VGA_WIDTH; x++) {
55 *vga_get_memory_address(x, y) = vga_get_char(VGA_LIGHT_GRAY, VGA_BLACK, ' ');
56 }
57 }
58
59 cursor_x = 0;
60 cursor_y = 0;
61 vga_set_cursor(0, 0);
62 }
63
64 void vga_print_char(const char character, const enum vga_color fg, const enum vga_color bg)
65 {
66 if (character == '\n') {
67 cursor_x = 0;
68 cursor_y++;
69 } else {
70 *vga_get_memory_address(cursor_x, cursor_y) = vga_get_char(fg, bg, character);
71 cursor_x++;
72 }
73
74 if (cursor_x >= VGA_WIDTH) {
75 cursor_x = 0;
76 cursor_y++;
77 }
78
79 if (cursor_y >= VGA_HEIGHT)
80 vga_scroll_up();
81
82 vga_set_cursor(cursor_x, cursor_y);
83 }
84
85 void vga_initialize()
86 {
87 uint8_t vga_misc = inb(0x3cc);
88 if (vga_misc&1)
89 crtc_port = 0x3d4;
90 else
91 crtc_port = 0x3b4;
92
93 vga_screen_clear();
94 }