Revision 177
moved all sources to src/
proj/keyboard.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "keyboard.h" |
|
4 |
|
|
5 |
#include "kbc.h" |
|
6 |
#include "kbc_macros.h" |
|
7 |
#include "utils.h" |
|
8 |
#include "errors.h" |
|
9 |
#include "proj_func.h" |
|
10 |
|
|
11 |
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id) { |
|
12 |
if (interrupt_id == NULL) return NULL_PTR; |
|
13 |
*interrupt_id = interrupt_bit; |
|
14 |
if(sys_irqsetpolicy(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR; |
|
15 |
return SUCCESS; |
|
16 |
} |
|
17 |
|
|
18 |
int done = 1; |
|
19 |
int sz = 1; |
|
20 |
int got_error_keyboard = SUCCESS; |
|
21 |
|
|
22 |
void (kbc_ih)(void) { |
|
23 |
if(done) { sz = 1; } |
|
24 |
else sz++; |
|
25 |
uint8_t status = 0; |
|
26 |
got_error_keyboard = SUCCESS; |
|
27 |
if ((got_error_keyboard = util_sys_inb(STATUS_REG, &status))) return; |
|
28 |
if (status & (TIME_OUT_REC | PARITY_ERROR)) { |
|
29 |
got_error_keyboard = 1; |
|
30 |
return; |
|
31 |
} |
|
32 |
if ((status & OUT_BUF_FUL) == 0 || (status & AUX_MOUSE) != 0) { |
|
33 |
got_error_keyboard = READ_ERROR; |
|
34 |
return; |
|
35 |
} |
|
36 |
uint8_t byte = 0; |
|
37 |
if ((got_error_keyboard = util_sys_inb(OUTPUT_BUF, &byte))) return; |
|
38 |
|
|
39 |
scancode[sz-1] = byte; |
|
40 |
done = !(TWO_BYTE_CODE == byte); |
|
41 |
|
|
42 |
if (done) update_movement(); |
|
43 |
|
|
44 |
} |
|
45 |
|
|
46 |
int (keyboard_poll)(uint8_t bytes[], uint8_t *size){ |
|
47 |
int ret = 0; |
|
48 |
if(bytes == NULL || size == NULL) return NULL_PTR; |
|
49 |
uint8_t c; |
|
50 |
if((ret = kbc_read_byte(&c))) return ret; |
|
51 |
if(c == TWO_BYTE_CODE){ |
|
52 |
if((ret = kbc_read_byte(&bytes[1]))) return ret; |
|
53 |
bytes[0] = c; |
|
54 |
*size = 2; |
|
55 |
}else{ |
|
56 |
bytes[1] = 0; |
|
57 |
bytes[0] = c; |
|
58 |
*size = 1; |
|
59 |
} |
|
60 |
return SUCCESS; |
|
61 |
} |
|
62 | 0 |
proj/fast_math.c | ||
---|---|---|
1 |
#include "fast_math.h" |
|
2 |
|
|
3 |
#include <math.h> |
|
4 |
|
|
5 |
double fm_sin(double x){ |
|
6 |
if(x < 0.0) return -fm_sin(-x); |
|
7 |
if(x > 2.0*M_PI) return fm_sin(x-2.0*M_PI); |
|
8 |
if(x > M_PI) return -fm_sin(x-M_PI); |
|
9 |
if(x > 0.5*M_PI) x = M_PI - x; |
|
10 |
double x2 = x*x; |
|
11 |
double x3 = x*x2; |
|
12 |
double x5 = x3*x2; |
|
13 |
//double x7 = x5*x2; |
|
14 |
return x-x3*0.1666666666666666666666+x5*0.008333333333333333333333;//-x7*0.0001984126984127; |
|
15 |
} |
|
16 |
|
|
17 |
double fm_cos(double x){ |
|
18 |
if(x < 0.0) x = -x; |
|
19 |
if(x > 2.0*M_PI) return fm_cos(x-2.0*M_PI); |
|
20 |
if(x > M_PI) x = 2.0*M_PI-x; |
|
21 |
if(x > 0.5*M_PI) return -fm_cos(M_PI-x); |
|
22 |
double x2 = x*x; |
|
23 |
double x4 = x2*x2; |
|
24 |
double x6 = x4*x2; |
|
25 |
//double x8 = x4*x4; |
|
26 |
return 1.0-x2*0.5+x4*0.041666666666666666666666-x6*0.0013888888888888888888888;//+x8*0.000024801587; |
|
27 |
} |
|
28 | 0 |
proj/utils.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "utils.h" |
|
4 |
|
|
5 |
#include <stdint.h> |
|
6 |
#include "errors.h" |
|
7 |
|
|
8 |
int(util_get_LSB)(uint16_t val, uint8_t *lsb) { |
|
9 |
if (lsb == NULL) return NULL_PTR; |
|
10 |
*lsb = val; |
|
11 |
return SUCCESS; |
|
12 |
} |
|
13 |
|
|
14 |
int(util_get_MSB)(uint16_t val, uint8_t *msb) { |
|
15 |
if (msb == NULL) return NULL_PTR; |
|
16 |
*msb = (val >> 8); |
|
17 |
return SUCCESS; |
|
18 |
} |
|
19 |
|
|
20 |
int (util_sys_inb)(int port, uint8_t *value) { |
|
21 |
if(value == NULL) return NULL_PTR; |
|
22 |
uint32_t n = 0; |
|
23 |
if(sys_inb(port, &n)) return READ_ERROR; |
|
24 |
*value = n; |
|
25 |
return SUCCESS; |
|
26 |
} |
|
27 |
|
|
28 |
int (unsubscribe_interrupt)(int *interrupt_id) { |
|
29 |
if (interrupt_id == NULL) return NULL_PTR; |
|
30 |
if(sys_irqrmpolicy(interrupt_id)) return UNSBCR_ERROR; |
|
31 |
return SUCCESS; |
|
32 |
} |
|
33 |
|
|
34 |
int32_t min(int32_t a, int32_t b){ return (b < a ? b : a); } |
|
35 |
int32_t max(int32_t a, int32_t b){ return (a < b ? b : a); } |
|
36 | 0 |
proj/timer.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "timer.h" |
|
4 |
|
|
5 |
#include "i8254.h" |
|
6 |
|
|
7 |
int (subscribe_timer_interrupt)(uint8_t interrupt_bit, int *interrupt_id) { |
|
8 |
if (interrupt_id == NULL) return 1; |
|
9 |
*interrupt_id = interrupt_bit; |
|
10 |
return (sys_irqsetpolicy(TIMER0_IRQ, IRQ_REENABLE, interrupt_id)); |
|
11 |
} |
|
12 |
|
|
13 |
uint32_t no_interrupts = 0; |
|
14 |
void (timer_int_handler)() { |
|
15 |
no_interrupts++; |
|
16 |
} |
|
17 | 0 |
proj/graph.c | ||
---|---|---|
1 |
#include "graph.h" |
|
2 |
#include "graph_macros.h" |
|
3 |
#include "errors.h" |
|
4 |
|
|
5 |
#include <lcom/lcf.h> |
|
6 |
|
|
7 |
#include <stdio.h> |
|
8 |
|
|
9 |
/// MACROS |
|
10 |
#define FAR2PHYS(n) ((((n)>>12) & 0xFFFFFFF0) + ((n) & 0x0000FFFF)) |
|
11 |
|
|
12 |
/// STRUCT |
|
13 |
typedef struct __attribute__((packed)) { |
|
14 |
|
|
15 |
char VbeSignature[4] ; |
|
16 |
uint16_t VbeVersion ; |
|
17 |
uint32_t OemStringPtr ; |
|
18 |
uint8_t Capabilities[4] ; |
|
19 |
uint32_t VideoModePtr ; |
|
20 |
uint16_t TotalMemory ; |
|
21 |
|
|
22 |
uint16_t OemSoftwareRev ; |
|
23 |
uint32_t OemVendorNamePtr ; |
|
24 |
uint32_t OemProductNamePtr ; |
|
25 |
uint32_t OemProductRevPtr ; |
|
26 |
char Reserved[222] ; |
|
27 |
|
|
28 |
char OemData[256] ; |
|
29 |
} VbeInfoBlock; |
|
30 |
|
|
31 |
static vbe_mode_info_t vbe_mem_info; |
|
32 |
|
|
33 |
/// PUBLIC GET |
|
34 |
uint16_t (graph_get_XRes) (void){ return vbe_mem_info.XResolution; } |
|
35 |
uint16_t (graph_get_YRes) (void){ return vbe_mem_info.YResolution; } |
|
36 |
|
|
37 |
/// PRIVATE GET |
|
38 |
static uint16_t (graph_get_bits_pixel) (void){ return vbe_mem_info.BitsPerPixel; } |
|
39 |
static uint16_t (graph_get_bytes_pixel) (void){ return (graph_get_bits_pixel() + 7) >> 3; } |
|
40 |
static phys_bytes (graph_get_phys_addr) (void){ return vbe_mem_info.PhysBasePtr; } |
|
41 |
static unsigned (graph_get_vram_size) (void){ return vbe_mem_info.XResolution * vbe_mem_info.YResolution * graph_get_bytes_pixel(); } |
|
42 |
//static uint16_t (graph_get_RedMaskSize) (void){ return vbe_mem_info.RedMaskSize ; } |
|
43 |
//static uint16_t (graph_get_GreenMaskSize)(void){ return vbe_mem_info.GreenMaskSize; } |
|
44 |
//static uint16_t (graph_get_BlueMaskSize) (void){ return vbe_mem_info.BlueMaskSize ; } |
|
45 |
|
|
46 |
static int (get_permission)(unsigned int base_addr, unsigned int size) { |
|
47 |
struct minix_mem_range mmr; |
|
48 |
mmr.mr_base = base_addr; |
|
49 |
mmr.mr_limit = base_addr + size; |
|
50 |
return sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mmr); |
|
51 |
} |
|
52 |
|
|
53 |
//static int (get_permissions_first_mbyte)(void) { |
|
54 |
// return get_permission(MBYTE_BASE, MBYTE_SIZE); |
|
55 |
//} |
|
56 |
|
|
57 |
/// MEMORY |
|
58 |
static void *video_mem = NULL; /** @brief Frame-buffer VM address. */ |
|
59 |
static uint8_t *video_buf = NULL; /** @brief Primary buffer for drawing before copying to video_mem. */ |
|
60 |
static mmap_t mem_map; |
|
61 |
static int (graph_free_memory)(void) { |
|
62 |
int r = SUCCESS; |
|
63 |
free(video_buf); video_buf = NULL; |
|
64 |
r = !lm_free(&mem_map); |
|
65 |
return r; |
|
66 |
} |
|
67 |
static int (graph_map_vram)(void) { |
|
68 |
int r; |
|
69 |
const unsigned vram_base = graph_get_phys_addr(); |
|
70 |
const unsigned vram_size = graph_get_vram_size(); |
|
71 |
if ((r = get_permission(vram_base, vram_size))) { |
|
72 |
if (graph_free_memory()) { |
|
73 |
printf("%s: lm_free failed\n", __func__); |
|
74 |
} |
|
75 |
panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r); |
|
76 |
} |
|
77 |
|
|
78 |
video_mem = vm_map_phys(SELF, (void *)vram_base, vram_size); |
|
79 |
|
|
80 |
if (video_mem == MAP_FAILED) { |
|
81 |
if (graph_free_memory()) { |
|
82 |
printf("%s: lm_free failed\n", __func__); |
|
83 |
} |
|
84 |
panic("%s: couldn't map video memory.", __func__); |
|
85 |
} |
|
86 |
|
|
87 |
video_buf = malloc(vram_size); |
|
88 |
|
|
89 |
return SUCCESS; |
|
90 |
} |
|
91 |
|
|
92 |
/// INFO GET |
|
93 |
static int (vbe_get_mode_information)(uint16_t mode) { |
|
94 |
memset(&vbe_mem_info, 0, sizeof(vbe_mode_info_t)); // reset values |
|
95 |
|
|
96 |
struct reg86 reg_86; |
|
97 |
memset(®_86, 0, sizeof(struct reg86)); // reset struct |
|
98 |
|
|
99 |
vbe_mode_info_t *virtual_addr = lm_alloc(sizeof(vbe_mode_info_t), &mem_map); |
|
100 |
|
|
101 |
reg_86.intno = VC_BIOS_SERV; |
|
102 |
reg_86.ah = VBE_CALL; |
|
103 |
reg_86.al = VBE_MD_INFO; |
|
104 |
reg_86.cx = mode; |
|
105 |
reg_86.es = PB2BASE(mem_map.phys); |
|
106 |
reg_86.di = PB2OFF(mem_map.phys); |
|
107 |
// BIOS CALL |
|
108 |
if (sys_int86(®_86) || reg_86.ah != AH_SUCCESS) { |
|
109 |
printf("%s: sys_int86 failed\n", __func__); |
|
110 |
if (graph_free_memory()) { |
|
111 |
printf("%s: lm_free failed\n", __func__); |
|
112 |
} |
|
113 |
return BIOS_CALL_ERROR; |
|
114 |
} |
|
115 |
|
|
116 |
memcpy((void*)&vbe_mem_info, (void*)virtual_addr, mem_map.size); |
|
117 |
return SUCCESS; |
|
118 |
} |
|
119 |
/* |
|
120 |
static int (vbe_get_controller_information)(vg_vbe_contr_info_t *info_p) { |
|
121 |
memset(info_p, 0, sizeof(vg_vbe_contr_info_t)); // reset values |
|
122 |
|
|
123 |
mmap_t controller_map; |
|
124 |
|
|
125 |
struct reg86 reg_86; |
|
126 |
memset(®_86, 0, sizeof(struct reg86)); // reset struct |
|
127 |
|
|
128 |
VbeInfoBlock *virtual_addr = lm_alloc(sizeof(VbeInfoBlock), &controller_map); |
|
129 |
|
|
130 |
uint32_t virtual_base = (uint32_t)(virtual_addr) - controller_map.phys; |
|
131 |
|
|
132 |
virtual_addr->VbeSignature[0] = 'V'; |
|
133 |
virtual_addr->VbeSignature[1] = 'B'; |
|
134 |
virtual_addr->VbeSignature[2] = 'E'; |
|
135 |
virtual_addr->VbeSignature[3] = '2'; |
|
136 |
|
|
137 |
|
|
138 |
reg_86.intno = VC_BIOS_SERV; |
|
139 |
reg_86.ah = VBE_CALL; |
|
140 |
reg_86.al = VBE_CTRL_INFO; |
|
141 |
reg_86.es = PB2BASE(controller_map.phys); |
|
142 |
reg_86.di = PB2OFF(controller_map.phys); |
|
143 |
// BIOS CALL |
|
144 |
if (sys_int86(®_86) || reg_86.ah != AH_SUCCESS) { |
|
145 |
printf("%s: sys_int86 failed\n", __func__); |
|
146 |
if (!lm_free(&controller_map)) { |
|
147 |
printf("%s: lm_free failed\n", __func__); |
|
148 |
} |
|
149 |
return BIOS_CALL_ERROR; |
|
150 |
} |
|
151 |
|
|
152 |
info_p->VBESignature[0] = virtual_addr->VbeSignature[0]; |
|
153 |
info_p->VBESignature[1] = virtual_addr->VbeSignature[1]; |
|
154 |
info_p->VBESignature[2] = virtual_addr->VbeSignature[2]; |
|
155 |
info_p->VBESignature[3] = virtual_addr->VbeSignature[3]; |
|
156 |
|
|
157 |
uint8_t lsb, msb; |
|
158 |
util_get_LSB(virtual_addr->VbeVersion, &lsb); |
|
159 |
util_get_MSB(virtual_addr->VbeVersion, &msb); |
|
160 |
info_p->VBEVersion[0] = lsb; |
|
161 |
info_p->VBEVersion[1] = msb; |
|
162 |
|
|
163 |
info_p->TotalMemory = (virtual_addr->TotalMemory << 6); |
|
164 |
|
|
165 |
// Convert Far Far Pointer to Virtual Address |
|
166 |
|
|
167 |
uint32_t phys_ptr = FAR2PHYS(virtual_addr->OemStringPtr); |
|
168 |
uint32_t virtual_ptr = phys_ptr + virtual_base; |
|
169 |
info_p->OEMString = (char*)(virtual_ptr); |
|
170 |
|
|
171 |
phys_ptr = FAR2PHYS(virtual_addr->VideoModePtr); |
|
172 |
virtual_ptr = phys_ptr + virtual_base; |
|
173 |
info_p->VideoModeList = (uint16_t*)(virtual_ptr); |
|
174 |
|
|
175 |
phys_ptr = FAR2PHYS(virtual_addr->OemVendorNamePtr); |
|
176 |
virtual_ptr = phys_ptr + virtual_base; |
|
177 |
info_p->OEMVendorNamePtr = (char*)(virtual_ptr); |
|
178 |
|
|
179 |
phys_ptr = FAR2PHYS(virtual_addr->OemProductNamePtr); |
|
180 |
virtual_ptr = phys_ptr + virtual_base; |
|
181 |
info_p->OEMProductNamePtr = (char*)(virtual_ptr); |
|
182 |
|
|
183 |
phys_ptr = FAR2PHYS(virtual_addr->OemProductRevPtr); |
|
184 |
virtual_ptr = phys_ptr + virtual_base; |
|
185 |
info_p->OEMProductRevPtr = (char*)(virtual_ptr); |
|
186 |
|
|
187 |
if (!lm_free(&controller_map)) { |
|
188 |
printf("%s: lm_free failed\n", __func__); |
|
189 |
return LCF_ERROR; |
|
190 |
} |
|
191 |
|
|
192 |
return SUCCESS; |
|
193 |
} |
|
194 |
*/ |
|
195 |
|
|
196 |
/// INIT |
|
197 |
/** |
|
198 |
* @brief |
|
199 |
* @param mode |
|
200 |
* @return |
|
201 |
*/ |
|
202 |
static int (graph_set_mode)(uint16_t mode) { |
|
203 |
struct reg86 reg_86; |
|
204 |
|
|
205 |
memset(®_86, 0, sizeof(struct reg86)); // reset struct |
|
206 |
|
|
207 |
// Set Reg86 |
|
208 |
reg_86.intno = VC_BIOS_SERV; |
|
209 |
reg_86.ah = VBE_CALL; |
|
210 |
reg_86.al = SET_VBE_MD; |
|
211 |
reg_86.bx = mode | LINEAR_FRAME_BUFFER_MD; |
|
212 |
|
|
213 |
// BIOS CALL |
|
214 |
if (sys_int86(®_86) || reg_86.ah != AH_SUCCESS) { |
|
215 |
printf("%s: sys_int86 failed\n", __func__); |
|
216 |
return BIOS_CALL_ERROR; |
|
217 |
} |
|
218 |
|
|
219 |
return SUCCESS; |
|
220 |
} |
|
221 |
int (graph_init)(uint16_t mode){ |
|
222 |
if (vbe_get_mode_information(mode)) { |
|
223 |
printf("%s: failed to get information for mode %x.\n", __func__, mode); |
|
224 |
return 1; |
|
225 |
} |
|
226 |
|
|
227 |
graph_map_vram(); // if function fails it aborts program |
|
228 |
|
|
229 |
if (graph_set_mode(mode)) { |
|
230 |
printf("%s: failed to set graphic mode %x.\n", __func__, mode); |
|
231 |
return 1; |
|
232 |
}; |
|
233 |
return SUCCESS; |
|
234 |
} |
|
235 |
|
|
236 |
/// CLEANUP |
|
237 |
int (graph_cleanup)(void){ |
|
238 |
int r = SUCCESS; |
|
239 |
if ((r = vg_exit())) |
|
240 |
printf("%s: vg_exit failed to exit to text mode.\n", __func__); |
|
241 |
if ((r = graph_free_memory())) |
|
242 |
printf("%s: lm_free failed\n", __func__); |
|
243 |
return r; |
|
244 |
} |
|
245 |
|
|
246 |
/// PIXEL DRAWING |
|
247 |
int (graph_set_pixel)(uint16_t x, uint16_t y, uint32_t color) { |
|
248 |
if (x >= vbe_mem_info.XResolution || y >= vbe_mem_info.YResolution) { |
|
249 |
//printf("%s: invalid pixel.\n", __func__); |
|
250 |
return OUT_OF_RANGE; |
|
251 |
} |
|
252 |
unsigned int pos = (x + y * vbe_mem_info.XResolution) * graph_get_bytes_pixel(); |
|
253 |
memcpy(video_buf + pos, &color, graph_get_bytes_pixel()); |
|
254 |
return SUCCESS; |
|
255 |
} |
|
256 |
int (graph_set_pixel_alpha)(uint16_t x, uint16_t y, uint32_t color, uint8_t alpha){ |
|
257 |
if (x >= vbe_mem_info.XResolution || y >= vbe_mem_info.YResolution) { |
|
258 |
//printf("%s: invalid pixel.\n", __func__); |
|
259 |
return OUT_OF_RANGE; |
|
260 |
} |
|
261 |
unsigned int pos = (x + y * vbe_mem_info.XResolution) * graph_get_bytes_pixel(); |
|
262 |
uint32_t color_; |
|
263 |
memcpy(&color_, video_buf + pos, graph_get_bytes_pixel()); |
|
264 |
float a = 1.0-(alpha&0xFF)/(float)0xFF; |
|
265 |
uint8_t r = GET_RED(color)*a + GET_RED(color_)*(1.0-a); |
|
266 |
uint8_t g = GET_GRE(color)*a + GET_GRE(color_)*(1.0-a); |
|
267 |
uint8_t b = GET_BLU(color)*a + GET_BLU(color_)*(1.0-a); |
|
268 |
return graph_set_pixel(x,y,SET_RGB(r,g,b)); |
|
269 |
//return set_pixel(x,y,color); |
|
270 |
} |
|
271 |
|
|
272 |
int (graph_clear_screen)(void){ |
|
273 |
//return graph_paint_screen(BLACK); |
|
274 |
memset(video_buf, 0, graph_get_vram_size()); |
|
275 |
return SUCCESS; |
|
276 |
} |
|
277 |
|
|
278 |
int (graph_draw)(void){ |
|
279 |
memcpy((uint8_t*)video_mem, video_buf, graph_get_vram_size()); |
|
280 |
return 0; |
|
281 |
} |
|
282 |
|
|
283 |
/// RECTANGLE |
|
284 |
int (graph_draw_hline)(uint16_t x, uint16_t y, uint16_t len, uint32_t color){ |
|
285 |
int r; |
|
286 |
for (uint16_t i = 0; i < len; i++) |
|
287 |
if ((r = graph_set_pixel(x + i, y, color))) return r; |
|
288 |
return SUCCESS; |
|
289 |
} |
|
290 |
|
|
291 |
int (graph_draw_rectangle)(uint16_t x, uint16_t y,uint16_t width, uint16_t height, uint32_t color) { |
|
292 |
int r; |
|
293 |
for (uint16_t i = 0; i < height; i++) |
|
294 |
if ((r = graph_draw_hline(x, y + i, width, color))) return r; |
|
295 |
return SUCCESS; |
|
296 |
} |
|
297 | 0 |
proj/proj_func.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "proj_func.h" |
|
4 |
|
|
5 |
#include "interrupts_func.h" |
|
6 |
#include "graph.h" |
|
7 |
#include "keyboard.h" |
|
8 |
#include "errors.h" |
|
9 |
#include "proj_macros.h" |
|
10 |
#include "utils.h" |
|
11 |
|
|
12 |
#include "kbc_macros.h" |
|
13 |
|
|
14 |
#include <math.h> |
|
15 |
|
|
16 |
int cleanup(void) { |
|
17 |
int r = SUCCESS; |
|
18 |
if ((r = unsubscribe_all())) |
|
19 |
printf("%s: failed to unsubscribe drivers.\n", __func__); |
|
20 |
if ((r = graph_cleanup())) |
|
21 |
printf("%s: graph cleanup failed\n", __func__); |
|
22 |
|
|
23 |
return r; |
|
24 |
} |
|
25 |
|
|
26 |
static int hor_mov = REST, ver_mov = REST; |
|
27 |
|
|
28 |
void update_movement(void) { |
|
29 |
static int w_pressed = 0, a_pressed = 0, s_pressed = 0, d_pressed = 0; |
|
30 |
if (sz == 1) { |
|
31 |
switch(scancode[0]) { |
|
32 |
case W_MAKE_CODE : w_pressed = 1; break; |
|
33 |
case W_BREAK_CODE : w_pressed = 0; break; |
|
34 |
case A_MAKE_CODE : a_pressed = 1; break; |
|
35 |
case A_BREAK_CODE : a_pressed = 0; break; |
|
36 |
case S_MAKE_CODE : s_pressed = 1; break; |
|
37 |
case S_BREAK_CODE : s_pressed = 0; break; |
|
38 |
case D_MAKE_CODE : d_pressed = 1; break; |
|
39 |
case D_BREAK_CODE : d_pressed = 0; break; |
|
40 |
} |
|
41 |
} |
|
42 |
ver_mov = s_pressed - w_pressed; |
|
43 |
hor_mov = d_pressed - a_pressed; |
|
44 |
} |
|
45 |
|
|
46 |
static int32_t mouse_x = 0, mouse_y = 0; |
|
47 |
|
|
48 |
void update_mouse_position(struct packet *p) { |
|
49 |
mouse_x = max(0, mouse_x + p->delta_x); |
|
50 |
mouse_x = min(mouse_x, graph_get_XRes() - 1); |
|
51 |
|
|
52 |
mouse_y = max(0, mouse_y - p->delta_y); |
|
53 |
mouse_y = min(mouse_y, graph_get_YRes() - 1); |
|
54 |
} |
|
55 |
|
|
56 |
int32_t get_mouse_X(void) { return mouse_x; } |
|
57 |
|
|
58 |
int32_t get_mouse_Y(void) { return mouse_y; } |
|
59 |
|
|
60 |
double get_mouse_angle(sprite_t *p) { |
|
61 |
return atan2(sprite_get_y(p) - mouse_y, mouse_x - sprite_get_x(p)); |
|
62 |
} |
|
63 |
|
|
64 |
int get_hor_movement(void) { return hor_mov; } |
|
65 |
|
|
66 |
int get_ver_movement(void) { return ver_mov; } |
|
67 | 0 |
proj/sprite.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "sprite.h" |
|
4 |
|
|
5 |
#include "graph.h" |
|
6 |
#include "utils.h" |
|
7 |
#include "fast_math.h" |
|
8 |
#include <math.h> |
|
9 |
|
|
10 |
struct sprite{ |
|
11 |
int16_t x, y; |
|
12 |
uint16_t w, h; |
|
13 |
int16_t u0, v0; |
|
14 |
float theta; |
|
15 |
uint8_t *map; |
|
16 |
}; |
|
17 |
|
|
18 |
sprite_t* (sprite_ctor)(const char **xpm, int u0, int v0){ |
|
19 |
sprite_t *ret = (sprite_t*)malloc(sizeof(sprite_t)); |
|
20 |
if(ret == NULL) return NULL; |
|
21 |
enum xpm_image_type type = XPM_8_8_8_8; |
|
22 |
xpm_image_t img; |
|
23 |
ret->map = xpm_load((xpm_map_t)xpm, type, &img); |
|
24 |
if(ret->map == NULL){ |
|
25 |
free(ret); |
|
26 |
return NULL; |
|
27 |
} |
|
28 |
ret->x = 0; |
|
29 |
ret->y = 0; |
|
30 |
ret->w = img.width; |
|
31 |
ret->h = img.height; |
|
32 |
ret->u0 = u0; |
|
33 |
ret->v0 = u0; |
|
34 |
ret->theta = 0; |
|
35 |
return ret; |
|
36 |
} |
|
37 |
void (sprite_dtor)(sprite_t *p){ |
|
38 |
if(p == NULL) return; |
|
39 |
if(p->map) free(p->map); |
|
40 |
free(p); |
|
41 |
} |
|
42 |
|
|
43 |
void (sprite_set_x) (sprite_t *p, int16_t x){ p->x = x; } |
|
44 |
void (sprite_set_y) (sprite_t *p, int16_t y){ p->y = y; } |
|
45 |
void (sprite_set_pos) (sprite_t *p, int16_t x, int16_t y){ sprite_set_x(p, x); sprite_set_y(p, y); } |
|
46 |
void (sprite_set_angle) (sprite_t *p, double angle){ p->theta = angle; } |
|
47 |
void (sprite_set_center)(sprite_t *p, int16_t u0, int16_t v0){ p->u0 = u0; p->v0 = v0; } |
|
48 |
|
|
49 |
int sprite_get_x(const sprite_t *p){ return p->x; } |
|
50 |
int sprite_get_y(const sprite_t *p){ return p->y; } |
|
51 |
int sprite_get_w(const sprite_t *p){ return p->w; } |
|
52 |
int sprite_get_h(const sprite_t *p){ return p->h; } |
|
53 |
|
|
54 |
void (sprite_src2pic)(const sprite_t *p, int16_t x, int16_t y, int16_t *u, int16_t *v){ |
|
55 |
int16_t dx = x - p->x; |
|
56 |
int16_t dy = y - p->y; |
|
57 |
double s = fm_sin(p->theta); |
|
58 |
double c = fm_cos(p->theta); |
|
59 |
*u = dx*c - dy*s + p->u0; |
|
60 |
*v = dx*s + dy*c + p->v0; |
|
61 |
} |
|
62 |
|
|
63 |
void (sprite_draw)(const sprite_t *p){ |
|
64 |
const int16_t diag = sqrt(p->w*p->w + p->h*p->h)+2; |
|
65 |
int16_t u, v; |
|
66 |
for(int16_t y = max(0,p->y-diag); y < min(p->y+diag,graph_get_YRes()); ++y){ |
|
67 |
for(int16_t x = max(0,p->x-diag); x < min(p->x+diag,graph_get_XRes()); ++x){ |
|
68 |
sprite_src2pic(p, x, y, &u, &v); |
|
69 |
if(0 <= u && u < p->w && 0 <= v && v < p->h){ |
|
70 |
uint8_t *m = p->map + (v*p->w + u)*4; |
|
71 |
uint32_t color = SET_RGB(*(m+2), *(m+1), *(m)); |
|
72 |
graph_set_pixel_alpha(p->x + x, p->y + y, color, *(m+3)); |
|
73 |
} |
|
74 |
} |
|
75 |
} |
|
76 |
} |
|
77 | 0 |
proj/proj.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
#include <lcom/proj.h> |
|
3 |
#include <lcom/liblm.h> |
|
4 |
|
|
5 |
#include <stdbool.h> |
|
6 |
#include <stdint.h> |
|
7 |
|
|
8 |
#include "i8254.h" |
|
9 |
#include "kbc_macros.h" |
|
10 |
#include "graph_macros.h" |
|
11 |
#include "mouse_macros.h" |
|
12 |
#include "proj_macros.h" |
|
13 |
#include "errors.h" |
|
14 |
|
|
15 |
#include "sprite.h" |
|
16 |
#include "kbc.h" |
|
17 |
#include "graph.h" |
|
18 |
#include "timer.h" |
|
19 |
#include "keyboard.h" |
|
20 |
#include "mouse.h" |
|
21 |
#include "utils.h" |
|
22 |
#include "interrupts_func.h" |
|
23 |
#include "proj_func.h" |
|
24 |
|
|
25 |
#include "fast_math.h" |
|
26 |
#include <math.h> |
|
27 |
|
|
28 |
#ifdef DIOGO |
|
29 |
#include "shooter.h" |
|
30 |
#include "pistol.xpm" |
|
31 |
#endif |
|
32 |
#ifdef TELMO |
|
33 |
#include "crosshair.h" |
|
34 |
#endif |
|
35 |
|
|
36 |
int main(int argc, char* argv[]) { |
|
37 |
|
|
38 |
lcf_set_language("EN-US"); |
|
39 |
|
|
40 |
//lcf_trace_calls("/home/lcom/labs/proj/trace.txt"); |
|
41 |
|
|
42 |
//lcf_log_output("/home/lcom/labs/proj/output.txt"); |
|
43 |
|
|
44 |
if (lcf_start(argc, argv)) return 1; |
|
45 |
|
|
46 |
lcf_cleanup(); |
|
47 |
|
|
48 |
return 0; |
|
49 |
} |
|
50 |
|
|
51 |
int(proj_main_loop)(int argc, char *argv[]) { |
|
52 |
|
|
53 |
int r; |
|
54 |
|
|
55 |
/// subscribe interrupts |
|
56 |
if (subscribe_all()) { return 1; } |
|
57 |
|
|
58 |
/// initialize graphics |
|
59 |
if(graph_init(GRAPH_MODE)){ |
|
60 |
printf("%s: failed to initalize graphics.\n", __func__); |
|
61 |
if (cleanup()) printf("%s: failed to cleanup.\n", __func__); |
|
62 |
return 1; |
|
63 |
} |
|
64 |
|
|
65 |
#ifdef DIOGO |
|
66 |
//printf("%d\n", 1000000-(int)(1000000*fm_sin(0.5*M_PI))); |
|
67 |
//printf("%d\n", (int)(1000000*fm_cos(0.5*M_PI))); |
|
68 |
/* |
|
69 |
clock_t t = clock(); |
|
70 |
sprite_t *shooter1 = get_shooter(); sprite_set_pos(shooter1, 100, 100); |
|
71 |
for(double angle = 0; angle <= 6.283185; angle += 0.006283185){ |
|
72 |
sprite_set_angle(shooter1, angle); |
|
73 |
graph_clear_screen(); |
|
74 |
sprite_draw(shooter1); |
|
75 |
graph_draw(); |
|
76 |
} |
|
77 |
t = clock() - t; |
|
78 |
printf("Time taken: %d/%d \n", t, CLOCKS_PER_SEC); |
|
79 |
sprite_dtor(shooter1); |
|
80 |
*/ |
|
81 |
#endif |
|
82 |
|
|
83 |
#ifdef TELMO |
|
84 |
sprite_t *crosshair = get_crosshair(); |
|
85 |
graph_clear_screen(); |
|
86 |
sprite_draw(crosshair); |
|
87 |
graph_draw(); |
|
88 |
#endif |
|
89 |
|
|
90 |
/// loop stuff |
|
91 |
int ipc_status; |
|
92 |
message msg; |
|
93 |
int good = 1; |
|
94 |
|
|
95 |
#ifdef DIOGO |
|
96 |
good = 0; |
|
97 |
#endif |
|
98 |
|
|
99 |
while (good) { |
|
100 |
/* Get a request message. */ |
|
101 |
if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) { |
|
102 |
printf("driver_receive failed with %d", r); |
|
103 |
continue; |
|
104 |
} |
|
105 |
if (is_ipc_notify(ipc_status)) { /* received notification */ |
|
106 |
switch (_ENDPOINT_P(msg.m_source)) { |
|
107 |
case HARDWARE: /* hardware interrupt notification */ |
|
108 |
for (uint32_t i = 0, n = 1; i < 32; i++, n <<= 1) { |
|
109 |
if (msg.m_notify.interrupts & n) { |
|
110 |
interrupt_handler(i); |
|
111 |
if ((scancode[0]) == ESC_BREAK_CODE) good = 0; |
|
112 |
#ifdef TELMO |
|
113 |
if (counter_mouse_ih >= 3) { |
|
114 |
struct packet pp = mouse_parse_packet(packet_mouse_ih); |
|
115 |
update_mouse_position(&pp); |
|
116 |
sprite_set_pos(crosshair, get_mouse_X(), get_mouse_Y()); |
|
117 |
printf("X: %d | Y: %d | XRES: %d | YRES: %d\n", get_mouse_X(), get_mouse_Y(), graph_get_XRes(), graph_get_YRes()); |
|
118 |
graph_clear_screen(); |
|
119 |
sprite_draw(crosshair); |
|
120 |
graph_draw(); |
|
121 |
counter_mouse_ih = 0; |
|
122 |
} |
|
123 |
#endif |
|
124 |
} |
|
125 |
} |
|
126 |
|
|
127 |
break; |
|
128 |
default: |
|
129 |
break; /* no other notifications expected: do nothing */ |
|
130 |
} |
|
131 |
} else { /* received standart message, not a notification */ |
|
132 |
/* no standart message expected: do nothing */ |
|
133 |
} |
|
134 |
#ifdef TELMO |
|
135 |
switch (get_hor_movement()) { |
|
136 |
case LEFT: |
|
137 |
printf("GOING LEFT.\n"); |
|
138 |
break; |
|
139 |
case RIGHT: |
|
140 |
printf("GOING RIGHT.\n"); |
|
141 |
break; |
|
142 |
} |
|
143 |
switch (get_ver_movement()) { |
|
144 |
case UP: |
|
145 |
printf("GOING UP.\n"); |
|
146 |
break; |
|
147 |
case DOWN: |
|
148 |
printf("GOING DOWN.\n"); |
|
149 |
break; |
|
150 |
} |
|
151 |
#endif |
|
152 |
} |
|
153 |
|
|
154 |
// Unsubscribe interrupts |
|
155 |
if (unsubscribe_all()) { |
|
156 |
if (cleanup()) |
|
157 |
printf("%s: failed to cleanup.\n", __func__); |
|
158 |
return 1; |
|
159 |
} |
|
160 |
|
|
161 |
|
|
162 |
if (cleanup()) { |
|
163 |
printf("%s: failed to cleanup.\n", __func__); |
|
164 |
return 1; |
|
165 |
} |
|
166 |
|
|
167 |
return 0; |
|
168 |
} |
|
169 | 0 |
proj/interrupts_func.c | ||
---|---|---|
1 |
#include "interrupts_func.h" |
|
2 |
#include "timer.h" |
|
3 |
#include "i8254.h" |
|
4 |
#include "kbc_macros.h" |
|
5 |
#include "keyboard.h" |
|
6 |
#include "mouse.h" |
|
7 |
#include "utils.h" |
|
8 |
#include "errors.h" |
|
9 |
|
|
10 |
#include <lcom/lcf.h> |
|
11 |
|
|
12 |
static int timer_subscribed = 0, timer_id; |
|
13 |
|
|
14 |
static int keyboard_subscribed = 0, kbc_id; |
|
15 |
|
|
16 |
static int mouse_subscribed = 0, mouse_id; |
|
17 |
|
|
18 |
static void (*const ih[])(void) = { timer_int_handler, |
|
19 |
kbc_ih, |
|
20 |
NULL, |
|
21 |
NULL, |
|
22 |
NULL, |
|
23 |
NULL, |
|
24 |
NULL, |
|
25 |
NULL, |
|
26 |
NULL, |
|
27 |
NULL, |
|
28 |
NULL, |
|
29 |
NULL, |
|
30 |
mouse_ih, |
|
31 |
NULL, |
|
32 |
NULL, |
|
33 |
NULL, |
|
34 |
NULL, |
|
35 |
NULL, |
|
36 |
NULL, |
|
37 |
NULL, |
|
38 |
NULL, |
|
39 |
NULL, |
|
40 |
NULL, |
|
41 |
NULL, |
|
42 |
NULL, |
|
43 |
NULL, |
|
44 |
NULL, |
|
45 |
NULL, |
|
46 |
NULL, |
|
47 |
NULL, |
|
48 |
NULL, |
|
49 |
NULL, |
|
50 |
}; |
|
51 |
|
|
52 |
int (subscribe_all)(void) { |
|
53 |
|
|
54 |
/// Timer interrupt handling |
|
55 |
timer_id = 0; |
|
56 |
if(subscribe_timer_interrupt(TIMER0_IRQ, &timer_id)) { |
|
57 |
printf("%s: failed to subscribe timer interrupts.\n", __func__); |
|
58 |
return SBCR_ERROR; |
|
59 |
} |
|
60 |
timer_subscribed = 1; |
|
61 |
|
|
62 |
/// Keyboard interrupt handling |
|
63 |
kbc_id = 0; |
|
64 |
if (subscribe_kbc_interrupt(KBC_IRQ, &kbc_id)) { |
|
65 |
printf("%s: failed to subscribe keyboard interrupts.\n", __func__); |
|
66 |
if (unsubscribe_all()) |
|
67 |
printf("%s: failed to unsubcribe driver, unexpected behaviour is expected.\n"); |
|
68 |
return SBCR_ERROR; |
|
69 |
} |
|
70 |
keyboard_subscribed = 1; |
|
71 |
|
|
72 |
/// Mouse interrupt handling |
|
73 |
mouse_id = 0; |
|
74 |
if (subscribe_mouse_interrupt(MOUSE_IRQ, &mouse_id)) { // subscribes mouse interrupts in exclusive mode |
|
75 |
printf("%s: failed to subscribe mouse interrupts.\n", __func__); |
|
76 |
if (unsubscribe_all()) |
|
77 |
printf("%s: failed to unsubcribe driver, unexpected behaviour is expected.\n"); |
|
78 |
return SBCR_ERROR; |
|
79 |
} |
|
80 |
mouse_subscribed = 1; |
|
81 |
if (sys_irqdisable(&mouse_id)) { // temporarily disables our interrupts notifications |
|
82 |
printf("%s: failed to disable mouse interrupts.\n", __func__); |
|
83 |
if (unsubscribe_all()) |
|
84 |
printf("%s: failed to unsubcribe driver, unexpected behaviour is expected.\n"); |
|
85 |
return SBCR_ERROR; |
|
86 |
} |
|
87 |
if (mouse_set_data_report(true)) { // enables mouse data reporting |
|
88 |
printf("%s: failed to enable mouse data reporting.\n", __func__); |
|
89 |
if (unsubscribe_all()) |
|
90 |
printf("%s: failed to unsubcribe driver, unexpected behaviour is expected.\n"); |
|
91 |
return SBCR_ERROR; |
|
92 |
} |
|
93 |
if (sys_irqenable(&mouse_id)) { // re-enables our interrupts notifications |
|
94 |
printf("%s: failed to enable mouse interrupts.\n", __func__); |
|
95 |
if (unsubscribe_all()) |
|
96 |
printf("%s: failed to unsubcribe driver, unexpected behaviour is expected.\n"); |
|
97 |
return SBCR_ERROR; |
|
98 |
} |
|
99 |
|
|
100 |
return SUCCESS; |
|
101 |
} |
|
102 |
|
|
103 |
int (unsubscribe_all)(void) { |
|
104 |
int r = SUCCESS; |
|
105 |
|
|
106 |
// Unsubscribe Timer Interrupts |
|
107 |
if (timer_subscribed) { |
|
108 |
if (unsubscribe_interrupt(&timer_id)) { |
|
109 |
printf("%s: failed to unsubcribe timer interrupts.\n"); |
|
110 |
r = UNSBCR_ERROR; |
|
111 |
} |
|
112 |
timer_subscribed = 0; |
|
113 |
} |
|
114 |
|
|
115 |
// Unsubscribe Keyboard interrupts |
|
116 |
if (keyboard_subscribed) { |
|
117 |
if (unsubscribe_interrupt(&kbc_id)) { |
|
118 |
printf("%s: failed to unsubcribe keyboard interrupts.\n"); |
|
119 |
r = UNSBCR_ERROR; |
|
120 |
} |
|
121 |
keyboard_subscribed = 0; |
|
122 |
} |
|
123 |
|
|
124 |
// Unsubscribe Mouse Interrupts |
|
125 |
if (mouse_subscribed) { |
|
126 |
if (sys_irqdisable(&mouse_id)) { // temporarily disables our interrupts notifications |
|
127 |
printf("%s: failed to disable mouse interrupts.\n"); |
|
128 |
r = UNSBCR_ERROR; |
|
129 |
} |
|
130 |
if (mouse_set_data_report(false)) { // disables mouse data reporting |
|
131 |
printf("%s: failed to disable mouse data reporting.\n"); |
|
132 |
r = UNSBCR_ERROR; |
|
133 |
} |
|
134 |
if (sys_irqenable(&mouse_id)) { // re-enables our interrupts notifications |
|
135 |
printf("%s: failed to enable mouse interrupts.\n"); |
|
136 |
r = UNSBCR_ERROR; |
|
137 |
} |
|
138 |
if (unsubscribe_interrupt(&mouse_id)) { // unsubscribes interrupts |
|
139 |
printf("%s: failed to unsubcribe mouse interrupts.\n"); |
|
140 |
r = UNSBCR_ERROR; |
|
141 |
} |
|
142 |
mouse_subscribed = 0; |
|
143 |
} |
|
144 |
|
|
145 |
return r; |
|
146 |
} |
|
147 |
|
|
148 |
void interrupt_handler(uint8_t handler) { |
|
149 |
if (handler >= 32) return; |
|
150 |
if ((*ih[handler]) == NULL) return; |
|
151 |
(*ih[handler])(); |
|
152 |
} |
|
153 | 0 |
proj/mouse.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "mouse.h" |
|
4 |
|
|
5 |
#include "errors.h" |
|
6 |
#include "kbc_macros.h" |
|
7 |
#include "mouse_macros.h" |
|
8 |
#include "kbc.h" |
|
9 |
|
|
10 |
int (subscribe_mouse_interrupt)(uint8_t interrupt_bit, int *interrupt_id) { |
|
11 |
if (interrupt_id == NULL) return NULL_PTR; |
|
12 |
*interrupt_id = interrupt_bit; |
|
13 |
if (sys_irqsetpolicy(MOUSE_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR; |
|
14 |
return SUCCESS; |
|
15 |
} |
|
16 |
|
|
17 |
int got_error_mouse_ih = 0; |
|
18 |
int counter_mouse_ih = 0; |
|
19 |
|
|
20 |
void (mouse_ih)(void) { |
|
21 |
uint8_t status = 0; |
|
22 |
got_error_mouse_ih = 0; |
|
23 |
if(counter_mouse_ih >= 3) counter_mouse_ih = 0; |
|
24 |
|
|
25 |
if ((got_error_mouse_ih = util_sys_inb(STATUS_REG, &status))) return; |
|
26 |
|
|
27 |
if (status & (TIME_OUT_REC | PARITY_ERROR)) { |
|
28 |
got_error_mouse_ih = OTHER_ERROR; |
|
29 |
return; |
|
30 |
} |
|
31 |
if (((status & AUX_MOUSE) == 0) || ((status & OUT_BUF_FUL) == 0)) { |
|
32 |
got_error_mouse_ih = READ_ERROR; |
|
33 |
return; |
|
34 |
} |
|
35 |
|
|
36 |
uint8_t byte = 0; |
|
37 |
|
|
38 |
if ((got_error_mouse_ih = util_sys_inb(OUTPUT_BUF, &byte))) return; |
|
39 |
|
|
40 |
/// This does not run if: I was expecting the first one but what I get is definitely not the first byte |
|
41 |
if((byte & FIRST_BYTE_ID) || counter_mouse_ih){ |
|
42 |
packet_mouse_ih[counter_mouse_ih++] = byte; |
|
43 |
} |
|
44 |
} |
|
45 |
|
|
46 |
struct packet (mouse_parse_packet)(const uint8_t *packet_bytes){ |
|
47 |
struct packet pp; |
|
48 |
pp.bytes[0] = packet_bytes[0]; |
|
49 |
pp.bytes[1] = packet_bytes[1]; |
|
50 |
pp.bytes[2] = packet_bytes[2]; |
|
51 |
pp.rb = pp.bytes[0] & RIGHT_BUTTON; |
|
52 |
pp.mb = pp.bytes[0] & MIDDLE_BUTTON; |
|
53 |
pp.lb = pp.bytes[0] & LEFT_BUTTON; |
|
54 |
pp.delta_x = sign_extend_byte((packet_bytes[0] & MSB_X_DELTA) != 0, pp.bytes[1]); |
|
55 |
pp.delta_y = sign_extend_byte((packet_bytes[0] & MSB_Y_DELTA) != 0, pp.bytes[2]); |
|
56 |
pp.x_ov = pp.bytes[0] & X_OVERFLOW; |
|
57 |
pp.y_ov = pp.bytes[0] & Y_OVERFLOW; |
|
58 |
return pp; |
|
59 |
} |
|
60 |
|
|
61 |
int mouse_poll(struct packet *pp, uint16_t period){ |
|
62 |
int ret = 0; |
|
63 |
|
|
64 |
uint8_t packet[3]; |
|
65 |
uint8_t byte; |
|
66 |
if ((ret = mouse_issue_cmd(READ_DATA))) return ret; |
|
67 |
for(unsigned i = 0; i < 3; ++i){ |
|
68 |
if((ret = mouse_poll_byte(&byte, period))) return ret; |
|
69 |
packet[i] = byte; |
|
70 |
} |
|
71 |
*pp = mouse_parse_packet(packet); |
|
72 |
return SUCCESS; |
|
73 |
} |
|
74 |
|
|
75 |
int (mouse_set_data_report)(int on){ |
|
76 |
if(on) return mouse_issue_cmd(ENABLE_DATA_REP); |
|
77 |
else return mouse_issue_cmd( DIS_DATA_REP); |
|
78 |
} |
|
79 |
|
|
80 |
int (mouse_read_data)(uint8_t *data, uint16_t period) { |
|
81 |
int ret; |
|
82 |
if ((ret = mouse_issue_cmd(READ_DATA))) return ret; |
|
83 |
if ((ret = mouse_poll_byte(data, period))) return ret; |
|
84 |
return SUCCESS; |
|
85 |
} |
|
86 |
|
|
87 |
int (mouse_issue_cmd)(uint32_t cmd) { |
|
88 |
int ret; |
|
89 |
uint8_t ack = 0; |
|
90 |
for (unsigned int i = 0; i < KBC_NUM_TRIES; i++) { |
|
91 |
if ((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret; |
|
92 |
if ((ret = kbc_issue_arg(cmd))) return ret; |
|
93 |
if ((ret = mouse_read_byte(&ack))) return ret; |
|
94 |
|
|
95 |
if (ack == ACK_OK) return SUCCESS; |
|
96 |
if (ack == ACK_ERROR) return INVALID_COMMAND; |
|
97 |
tickdelay(micros_to_ticks(DELAY)); |
|
98 |
} |
|
99 |
return TIMEOUT_ERROR; |
|
100 |
} |
|
101 |
|
|
102 |
int (mouse_read_byte)(uint8_t *byte) { |
|
103 |
int ret = 0; |
|
104 |
uint8_t stat; |
|
105 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){ |
|
106 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret; |
|
107 |
if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)) { |
|
108 |
if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR; |
|
109 |
if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret; |
|
110 |
else return SUCCESS; |
|
111 |
} |
|
112 |
tickdelay(micros_to_ticks(DELAY)); |
|
113 |
} |
|
114 |
return TIMEOUT_ERROR; |
|
115 |
} |
|
116 |
|
|
117 |
int (mouse_poll_byte)(uint8_t *byte, uint16_t period) { |
|
118 |
int ret = 0; |
|
119 |
uint8_t stat; |
|
120 |
while(true){ |
|
121 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret; |
|
122 |
if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)) { |
|
123 |
if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR; |
|
124 |
if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret; |
|
125 |
else return SUCCESS; |
|
126 |
} |
|
127 |
tickdelay(micros_to_ticks(DELAY)); |
|
128 |
} |
|
129 |
} |
|
130 |
|
|
131 |
int16_t (sign_extend_byte)(uint8_t sign_bit, uint8_t byte) { |
|
132 |
return (int16_t)(((0xFF * sign_bit)<<8) | byte); |
|
133 |
} |
|
134 | 0 |
proj/kbc.c | ||
---|---|---|
1 |
#include <lcom/lcf.h> |
|
2 |
|
|
3 |
#include "kbc.h" |
|
4 |
|
|
5 |
#include "kbc_macros.h" |
|
6 |
#include "utils.h" |
|
7 |
#include "errors.h" |
|
8 |
|
|
9 |
int (kbc_read_cmd)(uint8_t *cmd){ |
|
10 |
int ret = 0; |
|
11 |
if((ret = kbc_issue_cmd(READ_KBC_CMD))) return ret; |
|
12 |
if((ret = kbc_read_byte(cmd))) return ret; |
|
13 |
return SUCCESS; |
|
14 |
} |
|
15 |
|
|
16 |
int (kbc_change_cmd)(uint8_t cmd){ |
|
17 |
int ret = 0; |
|
18 |
if((ret = kbc_issue_cmd(WRITE_KBC_CMD))) return ret; |
|
19 |
if((ret = kbc_issue_arg(cmd))) return ret; |
|
20 |
return SUCCESS; |
|
21 |
} |
|
22 |
|
|
23 |
int (kbc_restore_kbd)(){ |
|
24 |
int ret = 0; |
|
25 |
uint8_t cmd = 0; |
|
26 |
if((ret = kbc_read_cmd(&cmd))) return ret; |
|
27 |
cmd = (cmd | INT_KBD) & (~DIS_KBD); |
|
28 |
if((ret = kbc_change_cmd(cmd))) return ret; |
|
29 |
return SUCCESS; |
|
30 |
} |
|
31 |
|
|
32 |
int (kbc_issue_cmd)(uint8_t cmd){ |
|
33 |
int ret = 0; |
|
34 |
uint8_t stat; |
|
35 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){ |
|
36 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret; |
|
37 |
if((stat&IN_BUF_FULL) == 0){ |
|
38 |
if(sys_outb(KBC_CMD, cmd)) return WRITE_ERROR; |
|
39 |
return SUCCESS; |
|
40 |
} |
|
41 |
tickdelay(micros_to_ticks(DELAY)); |
|
42 |
} |
|
43 |
return TIMEOUT_ERROR; |
|
44 |
} |
|
45 |
|
|
46 |
int (kbc_issue_arg)(uint8_t arg){ |
|
47 |
int ret = 0; |
|
48 |
uint8_t stat; |
|
49 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){ |
|
50 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret; |
|
51 |
if((stat&IN_BUF_FULL) == 0){ |
|
52 |
if(sys_outb(KBC_CMD_ARG, arg)) return WRITE_ERROR; |
|
53 |
return SUCCESS; |
|
54 |
} |
|
55 |
tickdelay(micros_to_ticks(DELAY)); |
|
56 |
} |
|
57 |
return TIMEOUT_ERROR; |
|
58 |
} |
|
59 |
|
|
60 |
int (kbc_read_byte)(uint8_t *byte){ |
|
61 |
int ret = 0; |
|
62 |
uint8_t stat; |
|
63 |
for(int i = 0; i < KBC_NUM_TRIES; ++i){ |
|
64 |
if((ret = util_sys_inb(STATUS_REG, &stat))) return ret; |
|
65 |
if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){ |
|
66 |
if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR; |
|
67 |
if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret; |
|
68 |
else return SUCCESS; |
|
69 |
} |
|
70 |
tickdelay(micros_to_ticks(DELAY)); |
|
71 |
} |
|
72 |
printf("Timing out\n"); |
|
73 |
return TIMEOUT_ERROR; |
|
74 |
} |
|
75 | 0 |
proj/src/fast_math.c | ||
---|---|---|
1 |
#include "fast_math.h" |
|
2 |
|
|
3 |
#include <math.h> |
|
4 |
|
|
5 |
double fm_sin(double x){ |
|
6 |
if(x < 0.0) return -fm_sin(-x); |
|
7 |
if(x > 2.0*M_PI) return fm_sin(x-2.0*M_PI); |
|
8 |
if(x > M_PI) return -fm_sin(x-M_PI); |
|
9 |
if(x > 0.5*M_PI) x = M_PI - x; |
|
10 |
double x2 = x*x; |
|
11 |
double x3 = x*x2; |
|
12 |
double x5 = x3*x2; |
|
13 |
//double x7 = x5*x2; |
|
14 |
return x-x3*0.1666666666666666666666+x5*0.008333333333333333333333;//-x7*0.0001984126984127; |
|
15 |
} |
|
16 |
|
|
17 |
double fm_cos(double x){ |
|
18 |
if(x < 0.0) x = -x; |
|
19 |
if(x > 2.0*M_PI) return fm_cos(x-2.0*M_PI); |
|
20 |
if(x > M_PI) x = 2.0*M_PI-x; |
|
21 |
if(x > 0.5*M_PI) return -fm_cos(M_PI-x); |
|
22 |
double x2 = x*x; |
|
23 |
double x4 = x2*x2; |
|
24 |
double x6 = x4*x2; |
|
25 |
//double x8 = x4*x4; |
|
26 |
return 1.0-x2*0.5+x4*0.041666666666666666666666-x6*0.0013888888888888888888888;//+x8*0.000024801587; |
|
27 |
} |
|
0 | 28 |
proj/src/graph.c | ||
---|---|---|
1 |
#include "graph.h" |
|
2 |
#include "graph_macros.h" |
|
3 |
#include "errors.h" |
|
4 |
|
|
5 |
#include <lcom/lcf.h> |
|
6 |
|
|
7 |
#include <stdio.h> |
|
8 |
|
|
9 |
/// MACROS |
|
10 |
#define FAR2PHYS(n) ((((n)>>12) & 0xFFFFFFF0) + ((n) & 0x0000FFFF)) |
|
11 |
|
|
12 |
/// STRUCT |
|
13 |
typedef struct __attribute__((packed)) { |
|
14 |
|
|
15 |
char VbeSignature[4] ; |
|
16 |
uint16_t VbeVersion ; |
|
17 |
uint32_t OemStringPtr ; |
|
18 |
uint8_t Capabilities[4] ; |
|
19 |
uint32_t VideoModePtr ; |
|
20 |
uint16_t TotalMemory ; |
|
21 |
|
|
22 |
uint16_t OemSoftwareRev ; |
|
23 |
uint32_t OemVendorNamePtr ; |
|
24 |
uint32_t OemProductNamePtr ; |
|
25 |
uint32_t OemProductRevPtr ; |
|
26 |
char Reserved[222] ; |
|
27 |
|
|
28 |
char OemData[256] ; |
|
29 |
} VbeInfoBlock; |
|
30 |
|
|
31 |
static vbe_mode_info_t vbe_mem_info; |
|
32 |
|
|
33 |
/// PUBLIC GET |
|
34 |
uint16_t (graph_get_XRes) (void){ return vbe_mem_info.XResolution; } |
|
35 |
uint16_t (graph_get_YRes) (void){ return vbe_mem_info.YResolution; } |
|
36 |
|
|
37 |
/// PRIVATE GET |
|
38 |
static uint16_t (graph_get_bits_pixel) (void){ return vbe_mem_info.BitsPerPixel; } |
|
39 |
static uint16_t (graph_get_bytes_pixel) (void){ return (graph_get_bits_pixel() + 7) >> 3; } |
|
40 |
static phys_bytes (graph_get_phys_addr) (void){ return vbe_mem_info.PhysBasePtr; } |
|
41 |
static unsigned (graph_get_vram_size) (void){ return vbe_mem_info.XResolution * vbe_mem_info.YResolution * graph_get_bytes_pixel(); } |
|
42 |
//static uint16_t (graph_get_RedMaskSize) (void){ return vbe_mem_info.RedMaskSize ; } |
|
43 |
//static uint16_t (graph_get_GreenMaskSize)(void){ return vbe_mem_info.GreenMaskSize; } |
|
44 |
//static uint16_t (graph_get_BlueMaskSize) (void){ return vbe_mem_info.BlueMaskSize ; } |
|
45 |
|
|
46 |
static int (get_permission)(unsigned int base_addr, unsigned int size) { |
|
47 |
struct minix_mem_range mmr; |
|
48 |
mmr.mr_base = base_addr; |
|
49 |
mmr.mr_limit = base_addr + size; |
|
50 |
return sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mmr); |
|
51 |
} |
|
52 |
|
|
53 |
//static int (get_permissions_first_mbyte)(void) { |
|
54 |
// return get_permission(MBYTE_BASE, MBYTE_SIZE); |
|
55 |
//} |
|
56 |
|
|
57 |
/// MEMORY |
|
58 |
static void *video_mem = NULL; /** @brief Frame-buffer VM address. */ |
|
59 |
static uint8_t *video_buf = NULL; /** @brief Primary buffer for drawing before copying to video_mem. */ |
|
60 |
static mmap_t mem_map; |
|
61 |
static int (graph_free_memory)(void) { |
|
62 |
int r = SUCCESS; |
|
63 |
free(video_buf); video_buf = NULL; |
|
64 |
r = !lm_free(&mem_map); |
|
65 |
return r; |
|
66 |
} |
|
67 |
static int (graph_map_vram)(void) { |
|
68 |
int r; |
|
69 |
const unsigned vram_base = graph_get_phys_addr(); |
|
70 |
const unsigned vram_size = graph_get_vram_size(); |
|
71 |
if ((r = get_permission(vram_base, vram_size))) { |
|
72 |
if (graph_free_memory()) { |
|
73 |
printf("%s: lm_free failed\n", __func__); |
|
74 |
} |
|
75 |
panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r); |
|
76 |
} |
|
77 |
|
|
78 |
video_mem = vm_map_phys(SELF, (void *)vram_base, vram_size); |
|
79 |
|
|
80 |
if (video_mem == MAP_FAILED) { |
|
81 |
if (graph_free_memory()) { |
|
82 |
printf("%s: lm_free failed\n", __func__); |
|
83 |
} |
|
84 |
panic("%s: couldn't map video memory.", __func__); |
|
85 |
} |
|
86 |
|
|
87 |
video_buf = malloc(vram_size); |
|
88 |
|
|
89 |
return SUCCESS; |
|
90 |
} |
|
91 |
|
|
92 |
/// INFO GET |
|
93 |
static int (vbe_get_mode_information)(uint16_t mode) { |
|
94 |
memset(&vbe_mem_info, 0, sizeof(vbe_mode_info_t)); // reset values |
|
95 |
|
|
96 |
struct reg86 reg_86; |
|
97 |
memset(®_86, 0, sizeof(struct reg86)); // reset struct |
|
98 |
|
|
99 |
vbe_mode_info_t *virtual_addr = lm_alloc(sizeof(vbe_mode_info_t), &mem_map); |
|
100 |
|
|
101 |
reg_86.intno = VC_BIOS_SERV; |
|
102 |
reg_86.ah = VBE_CALL; |
|
103 |
reg_86.al = VBE_MD_INFO; |
|
104 |
reg_86.cx = mode; |
|
105 |
reg_86.es = PB2BASE(mem_map.phys); |
|
106 |
reg_86.di = PB2OFF(mem_map.phys); |
|
107 |
// BIOS CALL |
|
108 |
if (sys_int86(®_86) || reg_86.ah != AH_SUCCESS) { |
|
109 |
printf("%s: sys_int86 failed\n", __func__); |
|
110 |
if (graph_free_memory()) { |
|
111 |
printf("%s: lm_free failed\n", __func__); |
|
112 |
} |
|
113 |
return BIOS_CALL_ERROR; |
|
114 |
} |
|
115 |
|
|
116 |
memcpy((void*)&vbe_mem_info, (void*)virtual_addr, mem_map.size); |
|
117 |
return SUCCESS; |
|
118 |
} |
|
119 |
/* |
|
120 |
static int (vbe_get_controller_information)(vg_vbe_contr_info_t *info_p) { |
|
121 |
memset(info_p, 0, sizeof(vg_vbe_contr_info_t)); // reset values |
|
122 |
|
|
123 |
mmap_t controller_map; |
|
124 |
|
|
125 |
struct reg86 reg_86; |
|
126 |
memset(®_86, 0, sizeof(struct reg86)); // reset struct |
|
127 |
|
|
128 |
VbeInfoBlock *virtual_addr = lm_alloc(sizeof(VbeInfoBlock), &controller_map); |
|
129 |
|
|
130 |
uint32_t virtual_base = (uint32_t)(virtual_addr) - controller_map.phys; |
|
131 |
|
|
132 |
virtual_addr->VbeSignature[0] = 'V'; |
|
133 |
virtual_addr->VbeSignature[1] = 'B'; |
|
134 |
virtual_addr->VbeSignature[2] = 'E'; |
|
135 |
virtual_addr->VbeSignature[3] = '2'; |
|
136 |
|
|
137 |
|
|
138 |
reg_86.intno = VC_BIOS_SERV; |
|
139 |
reg_86.ah = VBE_CALL; |
|
140 |
reg_86.al = VBE_CTRL_INFO; |
|
141 |
reg_86.es = PB2BASE(controller_map.phys); |
|
142 |
reg_86.di = PB2OFF(controller_map.phys); |
|
143 |
// BIOS CALL |
|
144 |
if (sys_int86(®_86) || reg_86.ah != AH_SUCCESS) { |
|
145 |
printf("%s: sys_int86 failed\n", __func__); |
|
146 |
if (!lm_free(&controller_map)) { |
|
147 |
printf("%s: lm_free failed\n", __func__); |
|
148 |
} |
|
149 |
return BIOS_CALL_ERROR; |
|
150 |
} |
|
151 |
|
|
152 |
info_p->VBESignature[0] = virtual_addr->VbeSignature[0]; |
|
153 |
info_p->VBESignature[1] = virtual_addr->VbeSignature[1]; |
|
154 |
info_p->VBESignature[2] = virtual_addr->VbeSignature[2]; |
|
155 |
info_p->VBESignature[3] = virtual_addr->VbeSignature[3]; |
|
156 |
|
|
157 |
uint8_t lsb, msb; |
|
158 |
util_get_LSB(virtual_addr->VbeVersion, &lsb); |
|
159 |
util_get_MSB(virtual_addr->VbeVersion, &msb); |
|
160 |
info_p->VBEVersion[0] = lsb; |
|
161 |
info_p->VBEVersion[1] = msb; |
|
162 |
|
|
163 |
info_p->TotalMemory = (virtual_addr->TotalMemory << 6); |
|
164 |
|
|
165 |
// Convert Far Far Pointer to Virtual Address |
|
166 |
|
|
167 |
uint32_t phys_ptr = FAR2PHYS(virtual_addr->OemStringPtr); |
|
168 |
uint32_t virtual_ptr = phys_ptr + virtual_base; |
|
169 |
info_p->OEMString = (char*)(virtual_ptr); |
|
170 |
|
|
171 |
phys_ptr = FAR2PHYS(virtual_addr->VideoModePtr); |
|
172 |
virtual_ptr = phys_ptr + virtual_base; |
|
173 |
info_p->VideoModeList = (uint16_t*)(virtual_ptr); |
|
174 |
|
|
175 |
phys_ptr = FAR2PHYS(virtual_addr->OemVendorNamePtr); |
|
176 |
virtual_ptr = phys_ptr + virtual_base; |
|
177 |
info_p->OEMVendorNamePtr = (char*)(virtual_ptr); |
|
178 |
|
|
179 |
phys_ptr = FAR2PHYS(virtual_addr->OemProductNamePtr); |
|
180 |
virtual_ptr = phys_ptr + virtual_base; |
|
181 |
info_p->OEMProductNamePtr = (char*)(virtual_ptr); |
|
182 |
|
|
183 |
phys_ptr = FAR2PHYS(virtual_addr->OemProductRevPtr); |
|
184 |
virtual_ptr = phys_ptr + virtual_base; |
|
185 |
info_p->OEMProductRevPtr = (char*)(virtual_ptr); |
|
186 |
|
|
187 |
if (!lm_free(&controller_map)) { |
|
188 |
printf("%s: lm_free failed\n", __func__); |
|
189 |
return LCF_ERROR; |
|
190 |
} |
|
191 |
|
|
192 |
return SUCCESS; |
|
193 |
} |
|
194 |
*/ |
|
195 |
|
|
196 |
/// INIT |
|
197 |
/** |
|
198 |
* @brief |
|
199 |
* @param mode |
|
200 |
* @return |
|
201 |
*/ |
|
202 |
static int (graph_set_mode)(uint16_t mode) { |
|
203 |
struct reg86 reg_86; |
|
204 |
|
|
205 |
memset(®_86, 0, sizeof(struct reg86)); // reset struct |
|
206 |
|
|
207 |
// Set Reg86 |
|
208 |
reg_86.intno = VC_BIOS_SERV; |
|
209 |
reg_86.ah = VBE_CALL; |
|
210 |
reg_86.al = SET_VBE_MD; |
|
211 |
reg_86.bx = mode | LINEAR_FRAME_BUFFER_MD; |
|
212 |
|
|
213 |
// BIOS CALL |
|
214 |
if (sys_int86(®_86) || reg_86.ah != AH_SUCCESS) { |
|
215 |
printf("%s: sys_int86 failed\n", __func__); |
|
216 |
return BIOS_CALL_ERROR; |
|
217 |
} |
|
218 |
|
|
219 |
return SUCCESS; |
|
220 |
} |
|
221 |
int (graph_init)(uint16_t mode){ |
|
222 |
if (vbe_get_mode_information(mode)) { |
|
223 |
printf("%s: failed to get information for mode %x.\n", __func__, mode); |
|
224 |
return 1; |
|
225 |
} |
|
226 |
|
|
227 |
graph_map_vram(); // if function fails it aborts program |
Also available in: Unified diff