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