-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkstd.c
More file actions
257 lines (210 loc) · 5.87 KB
/
kstd.c
File metadata and controls
257 lines (210 loc) · 5.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
#include <stdint.h>
#include <stddef.h>
#include "idt.h"
#include "vga.h"
#include "console.h"
volatile uint32_t ticks = 0;
volatile uint8_t waitmode = 0;
volatile char inputbuf[128] = {};
volatile uint8_t index = 0;
typedef void (*out_cb_t)(char *buf);
uint8_t active_tty = 0;
volatile out_cb_t callbacks[3];
static out_cb_t out = NULL;
void changeout(out_cb_t cb, size_t index) {
if(index < 3)
callbacks[index] = cb;
}
void resetout(void) {
out = NULL;
}
void* memset(void* dst, int v, size_t n) {
unsigned char* p = dst;
while (n--) *p++ = (unsigned char)v;
return dst;
}
int strcmp(const char *s1, const char *s2) {
while (*s1 && *s2) {
if (*s1 != *s2) return 0; // not equal
s1++;
s2++;
}
return (*s1 == 0 && *s2 == 0); // return 1 if both ended
}
int stoia(const char* buf){
int i = 0;
int num = 0;
while (buf[i])
{
if (buf[i] == '0' || buf[i] == '1' || buf[i] == '2' || buf[i] == '3' || buf[i] == '4' || buf[i] == '5' || buf[i] == '6' || buf[i] == '7' || buf[i] == '8' || buf[i] == '9' )
{
int val = buf[i] - 48;
num = num * 10 + val;
}
i++;
}
return num;
}
void itoa(int value, char* str, int base) {
char* ptr = str, *ptr1 = str, tmp_char;
int tmp_value;
if (value == 0) {
*ptr++ = '0';
*ptr = '\0';
return;
}
while (value != 0) {
tmp_value = value % base;
*ptr++ = (tmp_value < 10) ? (tmp_value + '0') : (tmp_value - 10 + 'A');
value /= base;
}
*ptr-- = '\0';
// reverse the string
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
}
const char scancode_to_ascii[128] = {
0, 27, '1','2','3','4','5','6','7','8','9','0','-','=', '\b', '\t',
'q','w','e','r','t','y','u','i','o','p','[',']','\n',0,'a','s',
'd','f','g','h','j','k','l',';','\'','`',0,'\\','z','x','c','v',
'b','n','m',',','.','/',0,'*',0,' ', /* rest zero */
};
// Assumes a single-character delimiter.
/**
* Splits a string in place based on a single character delimiter.
* The original string is modified by inserting null terminators.
*
* @param str The input string (char array) to be split. This is modified.
* @param delimiter The character used as the split point.
* @param tokens An array to store pointers to the start of each token.
* @param max_tokens The maximum number of tokens to find.
* @return The actual number of tokens found.
*/
int split(char* str, char delimiter, char* tokens[], int max_tokens) {
int token_count = 0;
char* p = str;
char* start = str;
// Iterate through the string until the end of the string (null terminator) is reached
while (*p && token_count < max_tokens) {
if (*p == delimiter) {
*p = '\0'; // Replace delimiter with null terminator to end the current token
tokens[token_count++] = start; // Store the start of the token
start = p + 1; // The next token starts after the delimiter
}
p++;
}
// Store the last token if there is space
if (token_count < max_tokens && start <= p) {
tokens[token_count++] = start;
}
return token_count;
}
void panic(const char *msg) {
terminal_writestring("KERNEL PANIC: ");
terminal_writestring(msg);
terminal_writestring("\n");
__asm__ volatile("cli");
while (1) { __asm__ volatile("hlt"); }
}
size_t strlen(const char* str) {
size_t len = 0;
while (str[len]) {
len++;
}
return len;
}
size_t read_ibuf(uint8_t *buf){
size_t len = strlen(inputbuf);
size_t i = 0;
while(i < len)
{
buf[i] = inputbuf[i];
i++;
}
return i;
}
void append_ibuf(uint8_t sc)
{
if(sc == 61){
terminal_writestring("Switching\n");
if(active_tty == 2){
active_tty = 0;
}
else {
active_tty++;
}
}
if(callbacks[active_tty] == NULL) return;
char ch = scancode_to_ascii[sc];
// Enter pressed -> finalize line
if (ch == '\n') {
terminal_writestring("\n");
callbacks[active_tty](inputbuf);
memset(inputbuf, 0, 128);
index = 0;
return;
}
// Backspace (scancode 14 is typical for PS/2 set 1)
if (sc == 14) {
if (index > 0) {
index--;
inputbuf[index] = 0;
terminal_removechar(); // assumes this erases last char on screen
}
return;
}
// Normal character append
if (index < 127) { // keep room for '\0'
inputbuf[index++] = ch;
inputbuf[index] = 0; // keep it a valid C-string
terminal_putchar(ch);
} else {
// overflow policy: reset (your choice)
memset(inputbuf, 0, 128);
index = 0;
}
}
void* memcpy(void* dst, const void* src, size_t n) {
unsigned char* d = dst;
const unsigned char* s = src;
while (n--) *d++ = *s++;
return dst;
}
//Depends on waitmode.
//If waitmode is set to 0 it will count assuming the speed is 18.2 Hz
//If waitmode is set to 1,The int passed = number of milliseconds to wait
void wait(int seconds){
if(waitmode == 0){
uint64_t current = ticks;
uint64_t target = 18.2*seconds + current;
while (1)
{
if(ticks >= target){
break;
}
}
}
else if (waitmode == 1)
{
uint64_t current = ticks;
uint64_t target = current+seconds;
while (1)
{
if (ticks >= target)
{
break;
}
}
}
}
void outb(uint16_t port, uint8_t val) {
__asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}
uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
return ret;
}