Project

General

Profile

Revision 109

rectangle implemented

View differences:

lab5/Makefile
2 2
PROG=lab5
3 3

  
4 4
# source code files to be compiled
5
SRCS = lab5.c graphics.c
5
SRCS = lab5.c graphics.c keyboard.c kbc.c utils.c
6 6

  
7 7
# additional compilation flags
8 8
# "-Wall -Wextra -Werror -I . -std=c11 -Wno-unused-parameter" are already set
lab5/graphics.c
123 123
}
124 124

  
125 125
int (vg_draw_hline)(uint16_t x, uint16_t y, uint16_t len, uint32_t color){
126
    int r;
127
    for (int i = 0; i < len; i++)
128
        if ((r = set_pixel(x + i, y, color))) return r;
126 129

  
130
    return SUCCESS;
131

  
127 132
    //uint8_t color8 = color;
128
    for(uint32_t i = 0; i < 256; ++i){
129
        set_pixel(x+i,y,i);
130
    }/*
131
    set_pixel(x,y,0);
132
    set_pixel(x+1,y,1);
133
    set_pixel(x+2,y,2);
134
    */
133
    //set_pixel(x,y,color);
134
    //set_pixel(x+1,y,color);
135
    //set_pixel(x+2,y,color);
135 136
    //*(p++) = color8;
136 137
    //*(p++) = color8;
137 138
    //*(p++) = color8;
......
145 146
        *((uint8_t*)(video_mem)+y*1024+x+len) = color8;
146 147
    }
147 148
    */
148
    return 0;
149 149
}
150

  
151
int (vg_draw_rectangle)(uint16_t x, uint16_t y,uint16_t width, uint16_t height, uint32_t color)	{
152
    int r;
153
    for (int i = 0; i < height; i++)
154
        if ((r = vg_draw_hline(x, y + i, width, color))) return r;
155

  
156
    return SUCCESS;
157
}
lab5/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 (unsubscribe_interrupt)(int *interrupt_id) {
10
    if (interrupt_id == NULL) return NULL_PTR;
11
    if(sys_irqrmpolicy(interrupt_id)) return UNSBCR_ERROR;
12
    return SUCCESS;
13
}
14

  
15
int (kbc_read_cmd)(uint8_t *cmd){
16
    int ret = 0;
17
    if((ret = kbc_issue_cmd(READ_KBC_CMD))) return ret;
18
    if((ret = kbc_read_byte(cmd))) return ret;
19
    return SUCCESS;
20
}
21

  
22
int (kbc_change_cmd)(uint8_t cmd){
23
    int ret = 0;
24
    if((ret = kbc_issue_cmd(WRITE_KBC_CMD))) return ret;
25
    if((ret = kbc_issue_arg(cmd))) return ret;
26
    return SUCCESS;
27
}
28

  
29
int (kbc_restore_kbd)(){
30
    int ret = 0;
31
    uint8_t cmd = 0;
32
    if((ret = kbc_read_cmd(&cmd))) return ret;
33
    cmd = (cmd | INT_KBD) & (~DIS_KBD);
34
    if((ret = kbc_change_cmd(cmd))) return ret;
35
    return SUCCESS;
36
}
37

  
38
int (kbc_issue_cmd)(uint8_t cmd){
39
    int ret = 0;
40
    uint8_t stat;
41
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
42
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
43
        if((stat&IN_BUF_FULL) == 0){
44
            if(sys_outb(KBC_CMD, cmd)) return WRITE_ERROR;
45
            return SUCCESS;
46
        }
47
        tickdelay(micros_to_ticks(DELAY));
48
    }
49
    return TIMEOUT_ERROR;
50
}
51

  
52
int (kbc_issue_arg)(uint8_t arg){
53
    int ret = 0;
54
    uint8_t stat;
55
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
56
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
57
        if((stat&IN_BUF_FULL) == 0){
58
            if(sys_outb(KBC_CMD_ARG, arg)) return WRITE_ERROR;
59
            return SUCCESS;
60
        }
61
        tickdelay(micros_to_ticks(DELAY));
62
    }
63
    return TIMEOUT_ERROR;
64
}
65

  
66
int (kbc_read_byte)(uint8_t *byte){
67
    int ret = 0;
68
    uint8_t stat;
69
    for(int i = 0; i < KBC_NUM_TRIES; ++i){
70
        if((ret = util_sys_inb(STATUS_REG, &stat))) return ret;
71
        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){
72
            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return OTHER_ERROR;
73
            if((ret = util_sys_inb(OUTPUT_BUF, byte))) return ret;
74
            else return SUCCESS;
75
        }
76
        tickdelay(micros_to_ticks(DELAY));
77
    }
78
    printf("Timing out\n");
79
    return TIMEOUT_ERROR;
80
}
0 81

  
lab5/kbc.h
1
/**
2
 * This file concerns everything related to the KBC (KeyBoard Controller, which
3
 * actually also manages the mouse)
4
 */
5

  
6
#ifndef KBC_H_INCLUDED
7
#define KBC_H_INCLUDED
8

  
9
/**
10
 * @brief Unsubcribes Interrupts
11
 * @param interrupt_id Interrupt ID, value via arguments on subscription of the interrupt_id
12
 * @see subscribe_kbc_interrupt, subscribe_timer_interrupt
13
 * @return Whether operation was sucessful or not
14
 */
15
int (unsubscribe_interrupt)(int *interrupt_id);
16

  
17
/**
18
 * @brief High-level function that reads the command byte of the KBC
19
 * @param cmd Pointer to variable where command byte read from KBC will be stored
20
 * @return 0 if operation was successful, 1 otherwise
21
 */
22
int (kbc_read_cmd)(uint8_t *cmd);
23

  
24
/**
25
 * @brief High-level function that changes the command byte of the KBC
26
 * @param cmd New value for command byte of KBC
27
 * @return 0 if operation was successful, 1 otherwise
28
 */
29
int (kbc_change_cmd)(uint8_t cmd);
30

  
31
/**
32
 * @brief High-level function that restores KBC to normal state
33
 * High-level function that restores KBC to normal state, because lcf_start
34
 * changes the command byte of KBC. If this function is not used, there is a
35
 * chance that the keyboard and keyboard interrupts remain disabled.
36
 * @return 0 if operation was successful, 1 otherwise
37
 */
38
int (kbc_restore_keyboard)();
39

  
40
/**
41
 * @brief Low-level function to issue a command to keyboard
42
 * @param cmd command to be issued
43
 * @return 0 if operation was successful, 1 otherwise
44
 */
45
int (kbc_issue_cmd)(uint8_t cmd);
46

  
47
/**
48
 * @brief Low-level function to issue an argument of a command
49
 * @param cmd argument to be issued
50
 * @return 0 if operation was successful, 1 otherwise
51
 */
52
int (kbc_issue_arg)(uint8_t arg);
53

  
54
/**
55
 * @brief Low-level function for reading byte from keyboard
56
 * Low-level function for reading byte from keyboard. Waits until output buffer
57
 * is full
58
 * @param value Pointer to variable where byte read from keyboard will be stored
59
 * @return 0 if operation was successful, 1 otherwise
60
 */
61
int (kbc_read_byte)(uint8_t *byte);
62

  
63
#endif //KBC_H_INCLUDED
0 64

  
lab5/kbc_macros.h
1
#ifndef KBC_MACROS_H_INCLUDED
2
#define KBC_MACROS_H_INCLUDED
3

  
4
/* KBC IRQ Line */
5

  
6
#define KBC_IRQ     1   /* @brief KBC Controller IRQ Line */
7
#define MOUSE_IRQ   12  /* @brief Mouse IRQ Line */
8

  
9
/* Delay for KBC */
10
#define DELAY           20000 /* @brief KBC Response Delay */
11
#define KBC_NUM_TRIES   20    /* @brief Number of tries to issue command before timeout */
12

  
13
/* I/O Ports Addresses */
14

  
15
#define KBC_CMD     0x64 /* @brief Address to send commands to KBC */
16
#define KBC_CMD_ARG 0x60 /* @brief Address to write KBC Command Arguments */
17
#define STATUS_REG  0x64 /* @brief KBC Status Register address */
18

  
19
#define OUTPUT_BUF  0x60 /* @brief Address of Output Buffer of KBC */
20

  
21
/* KBC Commands */
22
#define READ_KBC_CMD    0x20 /* @brief Read KBC Command Byte */
23
#define WRITE_KBC_CMD   0x60 /* @brief Write KBC Command Byte */
24
#define KBC_SELF_TEST   0xAA /* @brief KBC Diagnostic Tests */
25
#define KBC_INT_TEST    0xAB /* @brief Tests Keyboard Clock and Data lines */
26
#define KBC_INT_DISABLE 0xAD /* @brief Disable KBC Interface */
27
#define KBC_INT_ENABLE  0xAE /* @brief Enable KBC Interface */
28
#define MOUSE_DISABLE   0xA7 /* @brief Disable Mouse */
29
#define MOUSE_ENABLE    0xA8 /* @brief Enable Mouse */
30
#define MOUSE_INT_TEST  0xA9 /* @brief Tests Mouse data line */
31
#define MOUSE_WRITE_B   0xD4 /* @brief Write a byte directly to the mouse */
32

  
33
/* Status Byte Masking */
34

  
35
#define OUT_BUF_FUL     BIT(0) /* @brief Output Buffer State */
36
#define IN_BUF_FULL     BIT(1) /* @brief Input Buffer State */
37
#define SYS_FLAG        BIT(2) /* @brief System Flag */
38
#define DATA_CMD_WRITE  BIT(3) /* @brief Identifier of type of byte in input buffer */
39
#define INH_FLAG        BIT(4) /* @brief Keyboard inihibited */
40
#define AUX_MOUSE       BIT(5) /* @brief Mouse Data */
41
#define TIME_OUT_REC    BIT(6) /* @brief Time Out Error - Invalid Data */
42
#define PARITY_ERROR    BIT(7) /* @brief Parity Error - Invalid Data */
43

  
44
/* Scancode Constants */
45

  
46
#define ESC_BREAK_CODE  0x81    /* @brief ESC Break Code */
47
#define TWO_BYTE_CODE   0xE0    /* @brief First byte of a two byte Scancode */
48
#define BREAK_CODE_BIT  BIT(7)  /* @brief Bit to distinguish between Make code and Break code */
49

  
50
/* Command byte masks */
51
#define INT_KBD         BIT(0)  /* @brief Enable Keyboard Interrupts */
52
#define INT_MOU         BIT(1)  /* @brief Enable Mouse Interrupts */
53
#define DIS_KBD         BIT(4)  /* @brief Disable Keyboard */
54
#define DIS_MOU         BIT(5)  /* @brief Disable Mouse */
55

  
56
#endif //KBC_MACROS_H_INCLUDED
0 57

  
lab5/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

  
10
int (subscribe_kbc_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(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR;
14
    return SUCCESS;
15
}
16

  
17
int done = 1;
18
int sz = 1;
19
int got_error_keyboard = SUCCESS;
20

  
21
void (kbc_ih)(void) {
22
    if(done) sz = 1;
23
    else     sz++;
24
    uint8_t status = 0;
25
    got_error_keyboard = SUCCESS;
26
    if ((got_error_keyboard = util_sys_inb(STATUS_REG, &status))) return;
27
    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
28
        got_error_keyboard = 1;
29
        return;
30
    }
31
    if ((status & OUT_BUF_FUL) == 0 || (status & AUX_MOUSE) != 0) {
32
        got_error_keyboard = READ_ERROR;
33
        return;
34
    }
35
    uint8_t byte = 0;
36
    if ((got_error_keyboard = util_sys_inb(OUTPUT_BUF, &byte))) return;
37

  
38
    scancode[sz-1] = byte;
39
    done = !(TWO_BYTE_CODE == byte);
40
}
41

  
42
int (keyboard_poll)(uint8_t bytes[], uint8_t *size){
43
    int ret = 0;
44
    if(bytes == NULL || size == NULL) return NULL_PTR;
45
    uint8_t c;
46
    if((ret = kbc_read_byte(&c))) return ret;
47
    if(c == TWO_BYTE_CODE){
48
        if((ret = kbc_read_byte(&bytes[1]))) return ret;
49
        bytes[0] = c;
50
        *size = 2;
51
    }else{
52
        bytes[1] = 0;
53
        bytes[0] = c;
54
        *size = 1;
55
    }
56
    return SUCCESS;
57
}
0 58

  
lab5/keyboard.h
1
/**
2
 * This file concerns everything related to the keyboard
3
 */
4

  
5
#ifndef KEYBOARD_H_INCLUDED
6
#define KEYBOARD_H_INCLUDED
7

  
8
int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
9

  
10
uint8_t scancode[2];
11
int done;
12
int sz;
13
int got_error_keyboard;
14

  
15
void (kbc_ih)(void);
16

  
17
int (keyboard_poll)(uint8_t bytes[], uint8_t *size);
18

  
19
#endif //KEYBOARD_H_INCLUDED
0 20

  
lab5/lab5.c
7 7

  
8 8
#include "graphics.h"
9 9
#include "graphics_macros.h"
10
#include "keyboard.h"
11
#include "kbc.h"
12
#include "kbc_macros.h"
10 13

  
11 14
// Any header files included below this line should have been created by you
12 15

  
......
39 42
    if ((r = get_permissions_first_mbyte()))
40 43
        panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r);
41 44

  
42
    if (set_graphics_mode(mode)) {
43
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
44
        if (vg_exit())
45
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
46
        return 1;
47
    };
48

  
49 45
    if (vbe_get_mode_information(mode)) {
50 46
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
51 47
        if (vg_exit())
......
55 51

  
56 52
    map_vram(); // if function fails it aborts program
57 53

  
54
    if (set_graphics_mode(mode)) {
55
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
56
        if (vg_exit())
57
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
58
        return 1;
59
    };
60

  
58 61
    tickdelay(micros_to_ticks(delay*1e6));
59 62

  
60 63
    if (vg_exit()) {
......
76 79
int(video_test_rectangle)(uint16_t mode, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color) {
77 80
    int r;
78 81
    if ((r = get_permissions_first_mbyte()))
79
    panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r);
82
        panic("%s: sys_privctl (ADD MEM) failed: %d\n", __func__, r);
80 83

  
84
    if (vbe_get_mode_information(mode)) {
85
        printf("%s: failed to get information for mode %x.\n", __func__, mode);
86
        if (vg_exit())
87
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
88
        return 1;
89
    }
90

  
91
    map_vram(); // if function fails it aborts program
92

  
81 93
    if (set_graphics_mode(mode)) {
82 94
        printf("%s: failed to set graphic mode %x.\n", __func__, mode);
83 95
        if (vg_exit()) printf("%s: vg_exit failed to exit to text mode.\n", __func__);
84 96
        return 1;
85 97
    };
86 98

  
87
    vg_draw_hline(x, y, width, color);
88
    tickdelay(micros_to_ticks(1000000));
99
    if (vg_draw_rectangle(x, y, width, height, color)) {
100
        if (vg_exit()) {
101
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
102
            if (free_memory()) printf("%s: lm_free failed\n", __func__);
103
        }
104
        return 1;
105
    }
106

  
107
    /// loop stuff
108
    int ipc_status;
109
    message msg;
110
    /// Keyboard interrupt handling
111
    uint8_t kbc_irq_bit = KBC_IRQ;
112
    int kbc_id = 0;
113
    int kbc_irq = BIT(kbc_irq_bit);
114
    if (subscribe_kbc_interrupt(kbc_irq_bit, &kbc_id)) {
115
        if (vg_exit()) {
116
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
117
            if (free_memory()) printf("%s: lm_free failed\n", __func__);
118
        }
119
        return 1;
120
    }
121
    /// cycle
122
    int good = 1;
123
    while (good) {
124
        /* Get a request message. */
125
        if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
126
            printf("driver_receive failed with %d", r);
127
            continue;
128
        }
129
        if (is_ipc_notify(ipc_status)) { /* received notification */
130
            switch (_ENDPOINT_P(msg.m_source)) {
131
                case HARDWARE: /* hardware interrupt notification */
132
                    if (msg.m_notify.interrupts & kbc_irq) { /* subscribed interrupt */
133
                        kbc_ih();
134
                        if (scancode[0] == ESC_BREAK_CODE) good = 0;
135
                    }
136
                    break;
137
                default:
138
                    break; /* no other notifications expected: do nothing */
139
            }
140
        } else { /* received standart message, not a notification */
141
            /* no standart message expected: do nothing */
142
        }
143
    }
144

  
145
    if (unsubscribe_interrupt(&kbc_id)) {
146
        if (vg_exit()) {
147
            printf("%s: vg_exit failed to exit to text mode.\n", __func__);
148
            if (free_memory()) printf("%s: lm_free failed\n", __func__);
149
        }
150
        return 1;
151
    };
152

  
89 153
    if (vg_exit()) {
90 154
        printf("%s: vg_exit failed to exit to text mode.\n", __func__);
91 155
        if (free_memory()) printf("%s: lm_free failed\n", __func__);
92 156
        return 1;
93 157
    }
158

  
159
    if (free_memory()) {
160
        printf("%s: lm_free failed\n", __func__);
161
        return 1;
162
    }
163

  
94 164
    return 0;
95 165
}
96 166

  
lab5/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
#ifdef LAB3
21
    uint32_t sys_inb_counter = 0;
22
#endif
23

  
24
int (util_sys_inb)(int port, uint8_t *value) {
25
    if(value == NULL) return NULL_PTR;
26
    uint32_t n = 0;
27
    if(sys_inb(port, &n)) return READ_ERROR;
28
    *value = n;
29
    #ifdef LAB3
30
        ++sys_inb_counter;
31
    #endif
32
    return SUCCESS;
33
}
34

  
35
int16_t abs16(int16_t x) {
36
    return (x >= 0) ? (int16_t)(x) : (int16_t)(-x);
37
}
0 38

  
lab5/utils.h
1
#ifndef UTILS_H_INCLUDED
2
#define UTILS_H_INCLUDED
3

  
4
/**
5
 * @brief Gets the least significant byte of a 16-bit variable
6
 * @param val 16-bit variable
7
 * @param lsb Pointer to a 8-bit variable to store the value of the LSB
8
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
9
 */
10
int(util_get_LSB)(uint16_t val, uint8_t *lsb);
11

  
12
/**
13
 * @brief Gets the most significant byte of a 16-bit variable
14
 * @param val 16-bit variable
15
 * @param lsb Pointer to a 8-bit variable to store the value of the MSB
16
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
17
 */
18
int(util_get_MSB)(uint16_t val, uint8_t *msb);
19

  
20
#ifdef LAB3
21
    uint32_t sys_inb_counter;
22
#endif
23

  
24
/**
25
 * @brief sys_inb wrapper
26
 * @param port Port to read from
27
 * @param value Pointer to byte to store value read
28
 * @return ERROR_CODE code representing the result of the operation, SUCCESS code is returned if everything is OK
29
 */
30
int (util_sys_inb)(int port, uint8_t *value);
31

  
32
#endif //UTILS_H_INCLUDED
0 33

  

Also available in: Unified diff