]> git.dujemihanovic.xyz Git - nameless-os.git/blob - kernel/arch/x86/tty/tty.c
861610dde3bc80b08231cc8cbe745abd96dfd615
[nameless-os.git] / kernel / arch / x86 / tty / 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 volatile char *video_memory = (char *) 0xB8000; /* VGA VRAM starts at 0xB8000 */
9
10 static int cursor_x = 0; /* keep track of where cursor is */
11 static int cursor_y = 0;
12
13 char *hex_chars = "0123456789ABCDEF";
14
15 void screen_clear(void)
16 {
17 int x, y;
18 for ( y = 0; y < VGA_HEIGHT; y++ ) {
19 for ( x = 0; x < VGA_WIDTH; x++ ) {
20 video_memory[(y * VGA_WIDTH + x) * 2 + 1] = VGA_COLOR_LIGHT_GRAY;
21 video_memory[(y * VGA_WIDTH + x) * 2] = ' ';
22 }
23 }
24
25 cursor_x = 0;
26 cursor_y = 0;
27 }
28
29 void scroll_up(void)
30 {
31 int x, y;
32 for ( y = 1; y < VGA_HEIGHT; y++ ) {
33 for ( x = 0; x < VGA_WIDTH; x++ ) {
34 video_memory[((y - 1) * VGA_WIDTH + x) * 2] = video_memory[(y * VGA_WIDTH + x) * 2];
35 }
36 }
37 for ( x = 0; x < VGA_WIDTH; x++ ) {
38 video_memory[((VGA_HEIGHT - 1) * VGA_WIDTH + x) * 2] = ' ';
39 }
40 cursor_y = VGA_HEIGHT - 1;
41 }
42
43 void kprint(const char *string, uint8_t color)
44 {
45 char next_char;
46 uint8_t vga_misc_output;
47 uint16_t crtc_port;
48 next_char = *string;
49
50 while ( next_char != 0 ) {
51 if ( next_char == '\n') { cursor_x = 0; cursor_y++; }
52 else { video_memory[(cursor_y * VGA_WIDTH + cursor_x) * 2] = next_char; video_memory[((cursor_y * VGA_WIDTH + cursor_x++) * 2)+ 1] = color != 0 ? color : VGA_COLOR_LIGHT_GRAY; }
53 if ( cursor_x >= VGA_WIDTH ) { cursor_x = 0; cursor_y++; }
54 if ( cursor_y >= VGA_HEIGHT ) { scroll_up(); }
55 next_char = *++string;
56 }
57
58 vga_misc_output = inb(0x3CC);
59 if (vga_misc_output & 0x1 == 0) {
60 crtc_port = 0x3B4;
61 } else {
62 crtc_port = 0x3D4;
63 }
64
65 outb(crtc_port, 0xE);
66 outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) >> 8);
67 outb(crtc_port, 0xF);
68 outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) & 0xFF);
69 }
70
71 void kprintc(const char character, uint8_t color)
72 {
73 uint8_t vga_misc_output;
74 uint16_t crtc_port;
75
76 if ( character == '\n') { cursor_x = 0; cursor_y++; }
77 else { video_memory[(cursor_y * VGA_WIDTH + cursor_x) * 2] = character; video_memory[((cursor_y * VGA_WIDTH + cursor_x++) * 2)+ 1] = color != 0 ? color : VGA_COLOR_LIGHT_GRAY; }
78 if ( cursor_x >= VGA_WIDTH ) { cursor_x = 0; cursor_y++; }
79 if ( cursor_y >= VGA_HEIGHT ) { scroll_up(); }
80
81 vga_misc_output = inb(0x3CC);
82 if (vga_misc_output & 0x1 == 0) {
83 crtc_port = 0x3B4;
84 } else {
85 crtc_port = 0x3D4;
86 }
87
88 outb(crtc_port, 0xE);
89 outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) >> 8);
90 outb(crtc_port, 0xF);
91 outb(crtc_port + 1, (cursor_y * VGA_WIDTH + cursor_x) & 0xFF);
92
93 }
94
95 void kprintb(uint8_t byte)
96 {
97 uint8_t temp;
98 temp = byte >> 4;
99 kprint("0x", VGA_COLOR_LIGHT_GRAY);
100 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
101 temp = byte & 0xF;
102 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
103 }
104
105 void kprintw(uint16_t word)
106 {
107 uint8_t temp;
108 temp = word >> 12;
109 kprint("0x", VGA_COLOR_LIGHT_GRAY);
110 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
111 temp = (word >> 8) & 0xF;
112 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
113 temp = (word >> 4) & 0xF;
114 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
115 temp = word & 0xF;
116 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
117 }
118
119 void kprintd(uint32_t dword)
120 {
121 uint8_t temp;
122 temp = dword >> 28;
123 kprint("0x", VGA_COLOR_LIGHT_GRAY);
124 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
125 temp = (dword >> 24) & 0xF;
126 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
127 temp = (dword >> 20) & 0xF;
128 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
129 temp = (dword >> 16) & 0xF;
130 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
131 temp = (dword >> 12) & 0xF;
132 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
133 temp = (dword >> 8) & 0xF;
134 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
135 temp = (dword >> 4) & 0xF;
136 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
137 temp = dword & 0xF;
138 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
139 }
140
141 void kprintq(uint64_t qword)
142 {
143 uint8_t temp;
144 temp = qword >> 60;
145 kprint("0x", VGA_COLOR_LIGHT_GRAY);
146 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
147 temp = (qword >> 56) & 0xF;
148 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
149 temp = (qword >> 52) & 0xF;
150 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
151 temp = (qword >> 48) & 0xF;
152 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
153 temp = (qword >> 44) & 0xF;
154 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
155 temp = (qword >> 40) & 0xF;
156 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
157 temp = (qword >> 36) & 0xF;
158 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
159 temp = (qword >> 32) & 0xF;
160 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
161 temp = (qword >> 28) & 0xF;
162 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
163 temp = (qword >> 24) & 0xF;
164 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
165 temp = (qword >> 20) & 0xF;
166 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
167 temp = (qword >> 16) & 0xF;
168 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
169 temp = (qword >> 12) & 0xF;
170 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
171 temp = (qword >> 8) & 0xF;
172 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
173 temp = (qword >> 4) & 0xF;
174 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
175 temp = qword & 0xF;
176 kprintc(hex_chars[temp], VGA_COLOR_LIGHT_GRAY);
177 }
178
179 int kprintdec(uint32_t num)
180 {
181 char buffer[11];
182 int digits = 10;
183 /* TODO: make an actual memset function to use instead of this */
184 for (int i=0; i<11; i++) {
185 buffer[i] = 0;
186 }
187
188 /* put the numbers in the buffer */
189 for (int i=9; i>0 && num>0; i--) {
190 uint8_t currdigit = num%10;
191 buffer[i] = currdigit+'0';
192 num /= 10;
193 }
194
195 /* shift the array as much as needed */
196 while (*buffer == '\0') {
197 digits--;
198 for (int i=0; i<9; i++) {
199 buffer[i] = buffer[i+1];
200 }
201 }
202
203 /* zero out any leftovers */
204 if (digits < 10) {
205 for (int i=digits; i<10; i++) {
206 buffer[i] = '\0';
207 }
208 }
209
210 kprint(buffer, 0);
211 return digits;
212 }