-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathutil.c
160 lines (122 loc) · 2.28 KB
/
util.c
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
/*
* util.c - BIOS interface and other basic helpers
*
* author: luke8086
* license: GPL-2
*/
#include "util.h"
void
set_fs(uint16_t segment)
{
__asm__ volatile ("mov %0, %%fs" :: "r"(segment) : "memory");
}
void
set_gs(uint16_t segment)
{
__asm__ volatile ("mov %0, %%gs" :: "r"(segment) : "memory");
}
void *
memcpy(void *dest, const void *src, size_t n)
{
unsigned char *srcb = (unsigned char *)src;
unsigned char *destb = (unsigned char *)dest;
while (n--) {
*(destb++) = *(srcb++);
}
return dest;
}
size_t
strlen(const char *s)
{
size_t n = 0;
while (*s++)
++n;
return n;
}
uint16_t
rand(void)
{
/* See https://en.wikipedia.org/wiki/Xorshift */
static uint16_t seed = 0;
if (seed == 0)
seed = get_time();
seed ^= (seed << 13);
seed ^= (seed >> 9);
seed ^= (seed << 7);
return seed - 1;
}
void
toggle_cursor(int visible)
{
struct regs regs = {
.ah = 0x01,
.ch = (visible ? 0x06 : 0x20 ),
.cl = (visible ? 0x07 : 0x00 ),
};
intr(0x10, ®s);
}
uint16_t
get_cursor(void)
{
struct regs regs = { .ah = 0x03, .bh = 0x00 };
intr(0x10, ®s);
return regs.dx;
}
void
move_cursor(uint16_t pos)
{
struct regs regs = { .ah = 0x02, .bh = 0x00 };
regs.dx = pos;
intr(0x10, ®s);
}
void
put_char(char ascii)
{
struct regs regs = {
.ah = 0x0e,
.al = ascii,
.bh = 0x00,
};
intr(0x10, ®s);
}
void
put_string(char *s, uint8_t attr)
{
uint16_t pos = get_cursor();
uint16_t len = strlen(s);
struct regs regs = {
.ah = 0x13,
.al = 0x01,
.bh = 0x00,
.bl = attr,
};
regs.cx = len;
regs.dx = pos;
regs.bp = (uint16_t)(uint32_t)s;
intr(0x10, ®s);
}
int
check_keystroke(void)
{
struct regs regs = { .ah = 0x01 };
intr(0x16, ®s);
return !(regs.eflags & 0x0040);
}
struct keystroke
get_keystroke(void)
{
struct regs regs = { .ah = 0x00 };
intr(0x16, ®s);
struct keystroke ret = {
.scancode = regs.ah,
.ascii = regs.al,
};
return ret;
}
uint32_t
get_time(void)
{
struct regs regs = { .ah = 0x00 };
intr(0x1a, ®s);
return ((regs.cx << 16) | regs.dx);
}