-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathkernel.c
More file actions
205 lines (168 loc) · 5.28 KB
/
kernel.c
File metadata and controls
205 lines (168 loc) · 5.28 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
#define FONT8x16_IMPLEMENTATION
#include "font8x16.h"
#include <stdint.h>
typedef unsigned int uint32_t;
extern void irq12_handler_stub();
#define CURSOR_W 16
#define CURSOR_H 16
typedef struct {
uint16_t offset_low;
uint16_t selector;
uint8_t zero;
uint8_t type_attr;
uint16_t offset_high;
} __attribute__((packed)) idt_entry_t;
idt_entry_t idt[256];
struct {
uint16_t limit;
uint32_t base;
} __attribute__((packed)) idt_ptr;
unsigned char cursor_shape[CURSOR_H*2] = {
0b10000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11000000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11100000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11110000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11111000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11111100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11111110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11111111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11111110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11110100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b11001100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b10000110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b00000110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b00001100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b00011000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0b00110000,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
uint32_t mouse_x = 200;
uint32_t mouse_y = 200;
uint32_t saved_bg[CURSOR_H*CURSOR_W];
uint8_t mouse_packet[3];
int mouse_phase = 0;
static inline void outb(uint16_t port, uint8_t val) {
__asm__ volatile ("outb %0,%1" : : "a"(val), "Nd"(port));
}
static inline uint8_t inb(uint16_t port) {
uint8_t ret;
__asm__ volatile ("inb %1,%0" : "=a"(ret) : "Nd"(port));
return ret;
}
void draw_char(uint32_t* fb, int pitch, int x, int y, char c, uint32_t color) {
unsigned char* glyph = font8x16[(unsigned char)c];
for (int dy = 0; dy < 16; dy++) {
for (int dx = 0; dx < 8; dx++) {
if ((glyph[dy] << dx) & 0x80) {
fb[(y + dy) * (pitch / 4) + (x + dx)] = color;
}
}
}
}
void draw_string(uint32_t* fb, int pitch, int x, int y, const char* str, uint32_t color) {
for (int i = 0; str[i] != '\0'; i++) {
draw_char(fb, pitch, x + (i * 8), y, str[i], color);
}
}
void draw_rect(uint32_t* fb, int scanline, int x, int y, int w, int h, uint32_t color) {
for (int i = y; i < y + h; i++) {
for (int j = x; j < x + w; j++) {
fb[i * (scanline / 4) + j] = color;
}
}
}
void draw_cursor(uint32_t* fb, int pitch) {
for(int y=0;y<CURSOR_H;y++)
for(int x=0;x<CURSOR_W;x++)
saved_bg[y*CURSOR_W+x] = fb[(mouse_y+y)*(pitch/4)+(mouse_x+x)];
for(int y=0;y<CURSOR_H;y++)
for(int x=0;x<CURSOR_W;x++)
if(cursor_shape[y*2 + x/8] & (0x80>>(x%8)))
fb[(mouse_y+y)*(pitch/4)+(mouse_x+x)] = 0xFFFFFF;
}
void erase_cursor(uint32_t* fb,int pitch) {
for(int y=0;y<CURSOR_H;y++)
for(int x=0;x<CURSOR_W;x++)
fb[(mouse_y+y)*(pitch/4)+(mouse_x+x)] = saved_bg[y*CURSOR_W + x];
}
void mouse_write(uint8_t val) {
while (inb(0x64) & 0x02);
outb(0x64, 0xD4);
while (inb(0x64) & 0x02);
outb(0x60, val);
}
void idt_set_gate(int n, uint32_t handler) {
idt[n].offset_low = handler & 0xFFFF;
idt[n].selector = 0x08;
idt[n].zero = 0;
idt[n].type_attr = 0x8E;
idt[n].offset_high = (handler >> 16) & 0xFFFF;
}
void idt_load() {
idt_ptr.limit = sizeof(idt) - 1;
idt_ptr.base = (uint32_t)&idt;
__asm__ volatile("lidtl (%0)" : : "r"(&idt_ptr));
}
void setup_idt_irq() {
idt_set_gate(44, (uint32_t)irq12_handler_stub);
idt_load();
}
void mouse_init() {
mouse_write(0xF6);
mouse_write(0xF4);
}
void mouse_irq_handler(uint32_t* fb,int pitch,int width,int height) {
uint8_t data = inb(0x60);
if(mouse_phase == 0) {
if(data == 0xFA) mouse_phase = 1;
} else {
mouse_packet[mouse_phase-1] = data;
mouse_phase++;
if(mouse_phase == 4) {
int dx = (int8_t)mouse_packet[1];
int dy = (int8_t)mouse_packet[2];
erase_cursor(fb,pitch);
mouse_x += dx;
mouse_y -= dy;
if(mouse_x < 0) mouse_x = 0;
if(mouse_y < 0) mouse_y = 0;
if(mouse_x > width-CURSOR_W) mouse_x = width-CURSOR_W;
if(mouse_y > height-CURSOR_H) mouse_y = height-CURSOR_H;
draw_cursor(fb,pitch);
mouse_phase = 1;
}
}
outb(0x20,0x20);
}
extern void idt_set_gate(int n,uint32_t handler);
void pic_init() {
outb(0x20,0x11);
outb(0x21,0x20);
outb(0x21,0x04);
outb(0x21,0x01);
outb(0xA0,0x11);
outb(0xA1,0x28);
outb(0xA1,0x02);
outb(0xA1,0x01);
outb(0x21,0xF8);
outb(0xA1,0xEF);
}
void kmain(uint32_t magic, uint32_t* addr) {
(void)magic;
(void)addr;
uint32_t* fb = (uint32_t*)0xfd000000;
int width = 1024;
int height = 768;
int pitch = width * 4;
for(int i = 0; i < width * height; i++) fb[i] = 0x0000FF;
draw_rect(fb, pitch, 100, 100, 400, 300, 0xCCCCCC);
draw_rect(fb, pitch, 100, 100, 400, 30, 0x000088);
draw_rect(fb, pitch, 470, 105, 20, 20, 0xFF0000);
draw_string(fb, pitch, 110, 105, "Hello MiniOS Pro!", 0xFFFFFF);
draw_string(fb, pitch, 120, 150, "Hello", 0x000000);
setup_idt_irq();
pic_init();
mouse_init();
draw_cursor(fb, pitch);
while (1) {
}
}