Project

General

Profile

Revision 177

moved all sources to src/

View differences:

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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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(&reg_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
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff