fix dependency check logic cause config always disabled
[lunaix-os.git] / lunaix-os / hal / gfxa / vga / vga_rawtty.c
1 #include <klibc/string.h>
2 #include <lunaix/spike.h>
3 #include <lunaix/tty/tty.h>
4 #include <stdint.h>
5 #include <lunaix/owloysius.h>
6 #include <lunaix/mm/pagetable.h>
7 #include <lunaix/mm/mmio.h>
8
9 #include <asm/x86_pmio.h>
10
11 vga_attribute* tty_vga_buffer;
12
13 vga_attribute tty_theme_color = VGA_COLOR_BLACK;
14
15 inline void
16 tty_clear()
17 {
18     asm volatile("rep stosw" ::"D"(tty_vga_buffer),
19                  "c"(TTY_HEIGHT * TTY_WIDTH),
20                  "a"(tty_theme_color)
21                  : "memory");
22 }
23
24 void
25 tty_init(void* vga_buf)
26 {
27     tty_vga_buffer = (vga_attribute*)vga_buf;
28
29     tty_clear();
30
31     port_wrbyte(0x3D4, 0x0A);
32     port_wrbyte(0x3D5, (port_rdbyte(0x3D5) & 0xC0) | 13);
33
34     port_wrbyte(0x3D4, 0x0B);
35     port_wrbyte(0x3D5, (port_rdbyte(0x3D5) & 0xE0) | 15);
36 }
37
38 void
39 tty_set_cursor(u8_t x, u8_t y)
40 {
41     if (x >= TTY_WIDTH || y >= TTY_HEIGHT) {
42         x = y = 0;
43     }
44     u32_t pos = y * TTY_WIDTH + x;
45     port_wrbyte(0x3D4, 14);
46     port_wrbyte(0x3D5, pos / 256);
47     port_wrbyte(0x3D4, 15);
48     port_wrbyte(0x3D5, pos % 256);
49 }
50
51 void
52 tty_set_theme(vga_attribute fg, vga_attribute bg)
53 {
54     tty_theme_color = (bg << 4 | fg) << 8;
55 }
56
57 void
58 tty_flush_buffer(struct fifo_buf* buf)
59 {
60     int x = 0, y = 0;
61
62     // Clear screen
63     tty_clear();
64
65     char chr;
66     while (fifo_readone_async(buf, (u8_t*)&chr)) {
67         switch (chr) {
68             case '\t':
69                 x += 4;
70                 break;
71             case '\n':
72                 y++;
73                 // fall through
74             case '\r':
75                 x = 0;
76                 break;
77             default:
78                 *(tty_vga_buffer + x + y * TTY_WIDTH) =
79                     (tty_theme_color | chr);
80                 (x)++;
81                 break;
82         }
83
84         if (x >= TTY_WIDTH) {
85             x = 0;
86             y++;
87         }
88         if (y >= TTY_HEIGHT) {
89             y--;
90             break;
91         }
92     }
93
94     tty_set_cursor(x, y);
95 }
96
97 void
98 tty_clear_line(int line_num)
99 {
100     asm volatile("rep stosw" ::"D"(tty_vga_buffer + line_num * TTY_WIDTH),
101                  "c"(TTY_WIDTH),
102                  "a"(tty_theme_color)
103                  : "memory");
104 }
105
106 void
107 tty_put_str_at(char* str, int x, int y)
108 {
109     char c;
110     while ((c = (*str)) && y < TTY_HEIGHT) {
111         *(tty_vga_buffer + x + y * TTY_WIDTH) = c | tty_theme_color;
112         x++;
113         if (x >= TTY_WIDTH) {
114             y++;
115             x = 0;
116         }
117         str++;
118     }
119 }
120
121 static void
122 vga_rawtty_init()
123 {
124     // FIXME we should get rid of it at some point
125     tty_init((void*)ioremap(0xB8000, PAGE_SIZE));
126     tty_set_theme(VGA_COLOR_WHITE, VGA_COLOR_BLACK);
127 }
128 owloysius_fetch_init(vga_rawtty_init, on_earlyboot);