Index: lab4/kbc.c
===================================================================
--- lab4/kbc.c	(nonexistent)
+++ lab4/kbc.c	(revision 59)
@@ -0,0 +1,56 @@
+#include <lcom/lcf.h>
+
+#include "kbc.h"
+
+#include "kbc_macros.h"
+
+int (unsubscribe_interrupt)(int *interrupt_id) {
+    if (interrupt_id == NULL) return 1;
+    return sys_irqrmpolicy(interrupt_id);
+}
+
+int (kbc_read_cmd)(uint8_t *cmd){
+    if(kbc_issue_cmd(READ_KBC_CMD)) return 1;
+    if(kbc_read_byte(cmd)) return 1;
+    return 0;
+}
+
+int (kbc_change_cmd)(uint8_t cmd){
+    if(kbc_issue_cmd(WRITE_KBC_CMD)) return 1;
+    if(sys_outb(KBC_CMD_ARG, cmd)) return 1;
+    return 0;
+}
+
+int (kbc_restore_kbd)(){
+    uint8_t cmd = 0;
+    if(kbc_read_cmd(&cmd)) return 1;
+    cmd = (cmd | INT_KBD) & (~DIS_KBD) ;
+    if(kbc_change_cmd(cmd)) return 1;
+    return 0;
+}
+
+int (kbc_issue_cmd)(uint8_t cmd){
+    uint8_t stat;
+    for(int i = 0; i < KBC_NUM_TRIES; ++i){
+        if(util_sys_inb(STATUS_REG, &stat)) return 1;
+        if((stat&IN_BUF_FULL) == 0){
+            if(sys_outb(KBC_CMD, cmd)) return 1;
+            return 0;
+        }
+        tickdelay(micros_to_ticks(DELAY));
+    }
+    return 1;
+}
+
+int (kbc_read_byte)(uint8_t *byte){
+    uint8_t stat;
+    while(true){
+        if(util_sys_inb(STATUS_REG, &stat)) return 1;
+        if((stat&OUT_BUF_FUL) && (stat&AUX_MOUSE)==0){
+            if(stat & (PARITY_ERROR | TIME_OUT_REC)) return 1;
+            if(util_sys_inb(OUTPUT_BUF, byte)) return 1;
+            else return 0;
+        }
+        tickdelay(micros_to_ticks(DELAY));
+    }
+}

Property changes on: lab4/kbc.c
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: lab4/kbc_macros.h
===================================================================
--- lab4/kbc_macros.h	(nonexistent)
+++ lab4/kbc_macros.h	(revision 59)
@@ -0,0 +1,56 @@
+#ifndef _KBC_H_
+#define _KBC_H_
+
+/* KBC IRQ Line */
+
+#define KBC_IRQ     1   /* @brief KBC Controller IRQ Line */
+#define MOUSE_IRQ   12  /* @brief Mouse IRQ Line */
+
+/* Delay for KBC */
+#define DELAY           20000 /* @brief KBC Response Delay */
+#define KBC_NUM_TRIES   10    /* @brief Number of tries to issue command before timeout */
+
+/* I/O Ports Addresses */
+
+#define KBC_CMD     0x64 /* @brief Address to send commands to KBC */
+#define KBC_CMD_ARG 0x60 /* @brief Address to write KBC Command Arguments */
+#define STATUS_REG  0x64 /* @brief KBC Status Register address */
+
+#define OUTPUT_BUF  0x60 /* @brief Address of Output Buffer of KBC */
+
+/* KBC Commands */
+#define READ_KBC_CMD    0x20 /* @brief Read KBC Command Byte */
+#define WRITE_KBC_CMD   0x60 /* @brief Write KBC Command Byte */
+#define KBC_SELF_TEST   0xAA /* @brief KBC Diagnostic Tests */
+#define KBC_INT_TEST    0xAB /* @brief Tests Keyboard Clock and Data lines */
+#define KBC_INT_DISABLE 0xAD /* @brief Disable KBC Interface */
+#define KBC_INT_ENABLE  0xAE /* @brief Enable KBC Interface */
+#define MOUSE_DISABLE   0xA7 /* @brief Disable Mouse */
+#define MOUSE_ENABLE    0xA8 /* @brief Enable Mouse */
+#define MOUSE_INT_TEST  0xA9 /* @brief Tests Mouse data line */
+#define MOUSE_WRITE_B   0xD4 /* @brief Write a byte directly to the mouse */
+
+/* Status Byte Masking */
+
+#define OUT_BUF_FUL     BIT(0) /* @brief Output Buffer State */
+#define IN_BUF_FULL     BIT(1) /* @brief Input Buffer State */
+#define SYS_FLAG        BIT(2) /* @brief System Flag */
+#define DATA_CMD_WRITE  BIT(3) /* @brief Identifier of type of byte in input buffer */
+#define INH_FLAG        BIT(4) /* @brief Keyboard inihibited */
+#define AUX_MOUSE       BIT(5) /* @brief Mouse Data */
+#define TIME_OUT_REC    BIT(6) /* @brief Time Out Error - Invalid Data */
+#define PARITY_ERROR    BIT(7) /* @brief Parity Error - Invalid Data */
+
+/* Scancode Constants */
+
+#define ESC_BREAK_CODE  0x81    /* @brief ESC Break Code */
+#define TWO_BYTE_CODE   0xE0    /* @brief First byte of a two byte Scancode */
+#define BREAK_CODE_BIT  BIT(7)  /* @brief Bit to distinguish between Make code and Break code */
+
+/* Command byte masks */
+#define INT_KBD         BIT(0)  /* @brief Enable Keyboard Interrupts */
+#define INT_MOU         BIT(1)  /* @brief Enable Mouse Interrupts */
+#define DIS_KBD         BIT(4)  /* @brief Disable Keyboard */
+#define DIS_MOU         BIT(5)  /* @brief Disable Mouse */
+
+#endif

Property changes on: lab4/kbc_macros.h
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: lab4/kbd.c
===================================================================
--- lab4/kbd.c	(nonexistent)
+++ lab4/kbd.c	(revision 59)
@@ -0,0 +1,59 @@
+#include <lcom/lcf.h>
+
+#include "kbd.h"
+
+#include "kbc_macros.h"
+#include "kbc.h"
+
+int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
+    if (interrupt_id == NULL) return 1;
+    *interrupt_id = interrupt_bit;
+    return (sys_irqsetpolicy(KBC_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id));
+}
+
+void (kbc_ih)(void) {
+    uint8_t status = 0;
+    got_error = 0;
+
+    if (util_sys_inb(STATUS_REG, &status)) {
+        got_error = 1;
+        return;
+    }
+
+    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
+        got_error = 1;
+        return;
+    }
+
+    uint8_t byte = 0;
+
+    if (util_sys_inb(OUTPUT_BUF, &byte)) {
+        got_error = 1;
+        return;
+    }
+
+    if (two_byte_scancode) {
+        scancode[1] = byte;
+        two_byte_scancode = 0;
+    } else {
+        scancode[0] = byte;
+        two_byte_scancode = (byte == TWO_BYTE_CODE);
+    }
+
+}
+
+int (kbd_poll)(uint8_t bytes[], uint8_t *size){
+    if(bytes == NULL || size == NULL) return 1;
+    uint8_t c;
+    if(kbc_read_byte(&c)) return 1;
+    if(c == TWO_BYTE_CODE){
+        if(kbc_read_byte(&bytes[1])) return 1;
+        bytes[0] = c;
+        *size = 2;
+    }else{
+        bytes[1] = 0;
+        bytes[0] = c;
+        *size = 1;
+    }
+    return 0;
+}

Property changes on: lab4/kbd.c
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: lab4/kbd.h
===================================================================
--- lab4/kbd.h	(nonexistent)
+++ lab4/kbd.h	(revision 59)
@@ -0,0 +1,18 @@
+/**
+ * This file concerns everything related to the keyboard
+ */
+
+#ifndef KBD_H_INCLUDED
+#define KBD_H_INCLUDED
+
+int (subscribe_kbc_interrupt)(uint8_t interrupt_bit, int *interrupt_id);
+
+uint8_t scancode[2];
+int two_byte_scancode = 0;
+int got_error = 0;
+
+void (kbc_ih)(void);
+
+int (kbd_poll)(uint8_t bytes[], uint8_t *size);
+
+#endif //KBD_H_INCLUDED

Property changes on: lab4/kbd.h
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: lab4/mouse.c
===================================================================
--- lab4/mouse.c	(nonexistent)
+++ lab4/mouse.c	(revision 59)
@@ -0,0 +1,70 @@
+#include <lcom/lcf.h>
+
+#include "mouse.h"
+
+#include "errors.h"
+#include "kbc_macros.h"
+#include "mouse_macros.h"
+#include "kbc.h"
+
+int (subscribe_mouse_interrupt)(uint8_t interrupt_bit, int *interrupt_id) {
+    if (interrupt_id == NULL) return NULL_PTR;
+    *interrupt_id = interrupt_bit;
+    if (sys_irqsetpolicy(MOUSE_IRQ, IRQ_REENABLE | IRQ_EXCLUSIVE, interrupt_id)) return SBCR_ERROR;
+    return SUCCESS;
+}
+
+int got_error_mouse_ih = 0;
+uint8_t packet[3];
+int counter = 0;
+
+void (mouse_ih)(void) {
+    uint8_t status = 0;
+    got_error_mouse_ih = 0;
+    if(counter >= 3) counter = 0;
+
+    if (util_sys_inb(STATUS_REG, &status)) {
+        got_error_mouse_ih = 1;
+        return;
+    }
+
+    if (status & (TIME_OUT_REC | PARITY_ERROR)) {
+        got_error_mouse_ih = 1;
+        return;
+    }
+
+    uint8_t byte = 0;
+
+    if (util_sys_inb(OUTPUT_BUF, &byte)) {
+        got_error_mouse_ih = 1;
+        return;
+    }
+
+    /// This does not run if: I was expecting the first one but what I get is definitely not the first byte
+    if((byte & FIRST_BYTE_ID)  || counter){
+        packet[counter] = byte;
+        counter++;
+    }
+}
+
+struct packet (mouse_parse_packet)(const uint8_t *packet_bytes){
+    struct packet pp;
+    pp.bytes[0] = packet_bytes[0];
+    pp.bytes[1] = packet_bytes[1];
+    pp.bytes[2] = packet_bytes[2];
+    pp.rb       = pp.bytes[0] & RIGHT_BUTTON;
+    pp.mb       = pp.bytes[0] & MIDDLE_BUTTON;
+    pp.lb       = pp.bytes[0] & LEFT_BUTTON;
+    pp.delta_x  = pp.bytes[1];
+    pp.delta_y  = pp.bytes[2];
+    pp.x_ov     = pp.bytes[0] & X_OVERFLOW;
+    pp.y_ov     = pp.bytes[0] & Y_OVERFLOW;
+    return pp;
+}
+
+int (mouse_set_data_report)(int on){
+    int ret = 0;
+    if((ret = kbc_issue_cmd(MOUSE_WRITE_B))) return ret;
+    if(sys_outb(KBC_CMD_ARG, DIS_DATA_REP)) return WRITE_ERROR;
+    return SUCCESS;
+}

Property changes on: lab4/mouse.c
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: lab4/mouse_macros.h
===================================================================
--- lab4/mouse_macros.h	(nonexistent)
+++ lab4/mouse_macros.h	(revision 59)
@@ -0,0 +1,37 @@
+#ifndef _MOUSE_H_
+#define _MOUSE_H_
+
+/* Mouse Data Packet */
+// Byte 0 - Button States
+#define LEFT_BUTTON     BIT(0) /* @brief Left button click event*/
+#define RIGHT_BUTTON    BIT(1) /* @brief Right button click event */
+#define MIDDLE_BUTTON   BIT(2) /* @brief Middle button click event */
+#define FIRST_BYTE_ID   BIT(3) /* @brief Identifier of first byte of packet CAREFUL: Not 100% accurate */
+#define MSB_X_DELTA     BIT(4) /* @brief Most significant bit of X delta */
+#define MSB_Y_DELTA     BIT(5) /* @brief Most significant bit of Y delta */
+#define X_OVERFLOW      BIT(6) /* @brief X delta overflowed */
+#define Y_OVERFLOW      BIT(7) /* @brief Y delta overflowed */
+// Byte 1 - X delta
+// Byte 2 - Y delta
+
+/* Mouse Commands */
+#define RESET           0xFF /* @brief Reset mouse */
+#define RESEND          0xFE /* @brief Resend command */
+#define DEFAULT         0xF6 /* @brief Set default values */
+#define DIS_DATA_REP    0xF5 /* @brief Disable Data Reporting */
+#define ENABLE_DATA_REP 0xF4 /* @brief Enable Data Reporting */
+#define SET_SAMPLE_RT   0xF3 /* @brief Sets state sampling rate */
+#define SET_REMOTE_MD   0xF0 /* @brief Sets Mouse on Remote Mode, data on request */
+#define READ_DATA       0xEB /* @brief Sends data packet request */
+#define SET_STREAM_MD   0xEA /* @brief Sets mouse on Stream Mode, data on events */
+#define STATUS_REQUEST  0xE9 /* @brief Get mouse configuration */
+#define SET_RESOLUTION  0xE8 /* @brief Sets resolution for mouse movement */
+#define SCALING_ACC_MD  0xE7 /* @brief Sets scaling on acceleration mode */
+#define SCALING_LIN_MD  0xE6 /* @brief Sets scaling on linear mode */
+
+/* Mouse Controller Responses */
+#define ACK_OK      0xFA /* @brief Operation sucessful */
+#define ACK_INVALID 0xFE /* @brief Invalid Byte, first occurence */
+#define ACK_ERROR   0xFC /* @brief Invalid Byte on resend */
+
+#endif // _MOUSE_H_

Property changes on: lab4/mouse_macros.h
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
