diff options
-rw-r--r-- | src/Makefile | 4 | ||||
-rw-r--r-- | src/kernel.c | 34 | ||||
-rw-r--r-- | src/keyboard.c | 3 | ||||
-rw-r--r-- | src/keyboard.h | 36 | ||||
-rw-r--r-- | src/mouse.c | 78 | ||||
-rw-r--r-- | src/mouse.h | 28 | ||||
-rw-r--r-- | src/stage1_functions.asm | 2 |
7 files changed, 160 insertions, 25 deletions
diff --git a/src/Makefile b/src/Makefile index d0e9d68..3388eb4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,10 +13,10 @@ all: image.bin kernel.sym # + M * 512 (M is currently 7) = 3144 for kernel.bin # + 1 * 512 = 512 for magic.bin # (M + N + 1 is the number of sectors to be read in stage 2, as stage 1 -# loads only the first sector, so adapt NOF_LOAD_SECTORS to 24) +# loads only the first sector, so adapt NOF_LOAD_SECTORS to 27) image.bin: boot.bin kernel.bin magic.bin cat boot.bin kernel.bin > image.tmp - truncate -s 12288 image.tmp + truncate -s 13824 image.tmp cat image.tmp magic.bin > image.bin boot.bin: boot.asm boot_gdt.asm stage1_functions.asm stage2_functions.asm stage2_switch_mode.asm stage2_a20.asm diff --git a/src/kernel.c b/src/kernel.c index 386f4a4..fc5d1df 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -15,6 +15,11 @@ static jmp_buf panic_jmp_buf; +static void handle_keyboard_event( keyboard_event_t *event ); +static void handle_mouse_event( mouse_event_t *event ); + +// must be first entry in kernel.bin (0x8400) as stage 2 of +// the boot loader expects the entry point to be here! void entry( void ) { serial_t serial; @@ -41,14 +46,14 @@ void entry( void ) puts( "Initializing PS/2 keyboard" ); keyboard_t keyboard; - keyboard_init( &keyboard ); + keyboard_init( &keyboard, &handle_keyboard_event ); interrupt_handler_t keyboard_interrupt_handler; interrupt_handler_init( &keyboard_interrupt_handler, IRQ_BASE + 0x01, &interrupt, keyboard_handle_interrupt, &keyboard ); interrupts_register_interrupt_handler( keyboard_interrupt_handler ); puts( "Initializing PS/2 mouse" ); mouse_t mouse; - mouse_init( &mouse, vga.res_x, vga.res_y ); + mouse_init( &mouse, &handle_mouse_event, vga.res_x, vga.res_y ); interrupt_handler_t mouse_interrupt_handler; interrupt_handler_init( &mouse_interrupt_handler, IRQ_BASE + 0x0C, &interrupt, mouse_handle_interrupt, &mouse ); interrupts_register_interrupt_handler( mouse_interrupt_handler ); @@ -124,3 +129,28 @@ void kernel_panic( const char *format, ... ) longjmp( panic_jmp_buf, 47 ); } +static void handle_keyboard_event( keyboard_event_t *event ) +{ + puts( "KBD EVENT" ); +} + +static void handle_mouse_event( mouse_event_t *event ) +{ + switch( event->type ) { + case MOUSE_EVENT_TYPE_BUTTON_UP: + printf( "MOUSE UP %d AT X:%d, Y:%d\n", event->button, event->cursor_x, + event->cursor_y ); + break; + + case MOUSE_EVENT_TYPE_BUTTON_DOWN: + printf( "MOUSE DOWN %d AT X:%d, Y:%d\n", event->button, event->cursor_x, + event->cursor_y ); + break; + + case MOUSE_EVENT_TYPE_MOVE: + printf( "MOUSE MOVED FROM X:%d, Y:%d TO X:%d, Y:%d\n", + event->old_cursor_x, event->old_cursor_y, + event->cursor_x, event->cursor_y ); + break; + } +} diff --git a/src/keyboard.c b/src/keyboard.c index a2314da..2714ff2 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -53,7 +53,7 @@ static void write_data( keyboard_t *keyboard, uint8_t data ) port8_write( &keyboard->data_port, data ); } -void keyboard_init( keyboard_t *keyboard ) +void keyboard_init( keyboard_t *keyboard, keyboard_event_handler_t handler ) { memset( keyboard, 0, sizeof( keyboard_t ) ); @@ -61,6 +61,7 @@ void keyboard_init( keyboard_t *keyboard ) port8_init( &keyboard->data_port, 0x60 ); keyboard->shift = false; + keyboard->handler = handler; // first switch off port 1 send_command( keyboard, COMMAND_DISABLE_PORT1 ); diff --git a/src/keyboard.h b/src/keyboard.h index 74ab7af..7bc0c9b 100644 --- a/src/keyboard.h +++ b/src/keyboard.h @@ -7,15 +7,49 @@ #include "interrupts.h" #include "port.h" + +typedef enum { + KEYBOARD_EVENT_TYPE_KEY_PRESSED, + KEYBOARD_EVENT_TYPE_KEY_RELEASE +} keyboard_event_type_t; + +typedef enum { + KEYBOARD_MODIFIER_SHIFT = 0x01, + KEYBOARD_MODIFIER_CTRL = 0x02, + KEYBOARD_MODIFIER_ALT = 0x04 +} keyboard_modifier_mask_t; + +typedef enum { + KEYBOARD_KEY_ASCCI, + KEYBOARD_KEY_ESC, + KEYBOARD_KEY_TAB, + KEYBOARD_KEY_INS, + KEYBAORD_KEY_DEL, + KEYBAORD_KEY_BACKSPACE, + KEYBAORD_CURSOR_LEFT, + KEYBOARD_CURSOR_RIGHT, + KEYBOARD_CURSOR_UP, + KEYBOARD_CURSOR_DOWN +} keyboard_key_t; + +typedef struct { + keyboard_event_type_t type; + keyboard_modifier_mask_t modifiers; + keyboard_key_t key; + char ascii_key; +} keyboard_event_t; + +typedef void (*keyboard_event_handler_t)( keyboard_event_t *event ); typedef struct { interrupt_t *interrupts; port8_t command_port; port8_t data_port; bool shift; + keyboard_event_handler_t handler; } keyboard_t; -void keyboard_init( keyboard_t *keyboard ); +void keyboard_init( keyboard_t *keyboard, keyboard_event_handler_t handler ); uint32_t keyboard_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ); diff --git a/src/mouse.c b/src/mouse.c index 2a234ca..fda3806 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -2,6 +2,11 @@ #include <stdio.h> +// TODO: temporary, the driver should not use VGA directly +// but report mouse movements via callback handlers and +// there we draw the mouse cursor +#include "vga.h" + // status register on command port (read) #define STATUS_REG_OUTPUT_BUF_FULL 0x01 #define STATUS_REG_INPUT_BUF_FULL 0x02 @@ -23,6 +28,16 @@ #define DEFAULT_NOF_PACKETS 3 +// mouse data packet one +#define MOUSE_BYTE1_LEFT_BUTTON 0x01 +#define MOUSE_BYTE1_RIGHT_BUTTON 0x02 +#define MOUSE_BYTE1_MIDDLE_BUTTON 0x04 +#define MOUSE_BYTE1_ID_BIT 0x08 +#define MOUSE_BYTE1_X_SIGN 0x10 +#define MOUSE_BYTE1_Y_SIGN 0x20 +#define MOUSE_BYTE1_X_OVERFLOW 0x40 +#define MOUSE_BYTE1_Y_OVERFLOW 0x80 + static uint8_t read_data( mouse_t *mouse ) { while( ( port8_read( &mouse->command_port ) & STATUS_REG_OUTPUT_BUF_FULL ) == 0 ) { } @@ -41,7 +56,7 @@ static void write_data( mouse_t *mouse, uint8_t data ) port8_write( &mouse->data_port, data ); } -void mouse_init( mouse_t *mouse, uint32_t res_x, uint32_t res_y ) +void mouse_init( mouse_t *mouse, mouse_event_handler_t handler, uint32_t res_x, uint32_t res_y ) { memset( mouse, 0, sizeof( mouse_t ) ); @@ -52,6 +67,7 @@ void mouse_init( mouse_t *mouse, uint32_t res_x, uint32_t res_y ) mouse->res_y = res_y; mouse->cursor_x = mouse->res_x / 2; mouse->cursor_y = mouse->res_y / 2; + mouse->handler = handler; port8_init( &mouse->command_port, 0x64 ); port8_init( &mouse->data_port, 0x60 ); @@ -86,34 +102,64 @@ uint32_t mouse_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ) mouse->buf[mouse->offset] = port8_read( &mouse->data_port ); -// printf( "MOUSE %d 0x%X\n", mouse->offset, mouse->buf[mouse->offset] ); + printf( "MOUSE %d 0x%X\n", mouse->offset, mouse->buf[mouse->offset] ); switch( mouse->offset ) { case 0: + for( int i = 0; i < 3; i++ ) { + if( ( mouse->buf[0] & ( 0x01 << i ) ) != ( mouse->buttons & ( 0x01 << i ) ) ) { + mouse_event_t event; + event.button = i + 1; + if( mouse->buttons & ( 0x01 << i ) ) { + event.type = MOUSE_EVENT_TYPE_BUTTON_UP; + } else { + event.type = MOUSE_EVENT_TYPE_BUTTON_DOWN; + } + event.cursor_x = mouse->cursor_x; + event.cursor_y = mouse->cursor_y; + mouse->handler( &event ); + } + } + mouse->buttons = mouse->buf[0]; break; case 1: + // delay evaluation of move events till second byte break; case 2: - mouse->cursor_x += (int8_t)mouse->buf[1]; - mouse->cursor_y -= (int8_t)mouse->buf[2]; - if( mouse->cursor_x < 0 ) { - mouse->cursor_x = 0; - } - if( mouse->cursor_x > mouse->res_x ) { - mouse->cursor_x = mouse->res_x; - } - if( mouse->cursor_y < 0 ) { - mouse->cursor_y = 0; - } - if( mouse->cursor_y > mouse->res_y ) { - mouse->cursor_y = mouse->res_y; + if( mouse->buf[1] !=0 || mouse->buf[2] != 0 ) { + + mouse_event_t event; + event.type = MOUSE_EVENT_TYPE_MOVE; + event.old_cursor_x = mouse->cursor_x; + event.old_cursor_y = mouse->cursor_y; + + mouse->cursor_x += (int8_t)mouse->buf[1]; + mouse->cursor_y -= (int8_t)mouse->buf[2]; + if( mouse->cursor_x < 0 ) { + mouse->cursor_x = 0; + } + if( mouse->cursor_x > mouse->res_x ) { + mouse->cursor_x = mouse->res_x; + } + if( mouse->cursor_y < 0 ) { + mouse->cursor_y = 0; + } + if( mouse->cursor_y > mouse->res_y ) { + mouse->cursor_y = mouse->res_y; + } + + event.cursor_x = mouse->cursor_x; + event.cursor_y = mouse->cursor_y; + + mouse->handler( &event ); } + break; } - printf( "MOUSE X:%d Y:%d\n", mouse->cursor_x, mouse->cursor_y ); +// printf( "MOUSE X:%d Y:%d\n", mouse->cursor_x, mouse->cursor_y ); // advance offset mouse->offset = ( mouse->offset + 1 ) % mouse->nof_packets; diff --git a/src/mouse.h b/src/mouse.h index 74571c7..25ae231 100644 --- a/src/mouse.h +++ b/src/mouse.h @@ -8,21 +8,45 @@ #define MAX_NOF_MOUSE_PACKETS 5 +typedef enum { + MOUSE_EVENT_TYPE_BUTTON_UP, + MOUSE_EVENT_TYPE_BUTTON_DOWN, + MOUSE_EVENT_TYPE_MOVE +} mouse_event_type_t; + +typedef enum { + MOUSE_BUTTON_LEFT = 1, + MOUSE_BUTTON_RIGHT = 2, + MOUSE_BUTTON_MIDDLE = 3 +} mouse_button_t; + +typedef struct { + mouse_event_type_t type; + mouse_button_t button; + int32_t old_cursor_x; + int32_t old_cursor_y; + int32_t cursor_x; + int32_t cursor_y; +} mouse_event_t; + +typedef void (*mouse_event_handler_t)( mouse_event_t *event ); + typedef struct { interrupt_t *interrupts; port8_t command_port; port8_t data_port; int nof_packets; // 3 or more mouse packets uint8_t buf[MAX_NOF_MOUSE_PACKETS]; - uint8_t offset; uint8_t buttons; + uint8_t offset; uint32_t res_x; uint32_t res_y; int32_t cursor_x; int32_t cursor_y; + mouse_event_handler_t handler; } mouse_t; -void mouse_init( mouse_t *mouse, uint32_t res_x, uint32_t res_y ); +void mouse_init( mouse_t *mouse, mouse_event_handler_t handler, uint32_t res_x, uint32_t res_y ); uint32_t mouse_handle_interrupt( interrupt_handler_t *handler, uint32_t esp ); diff --git a/src/stage1_functions.asm b/src/stage1_functions.asm index e30f224..95d4489 100644 --- a/src/stage1_functions.asm +++ b/src/stage1_functions.asm @@ -2,7 +2,7 @@ ; 3 * 512 for bootloader stage2 and the kernel code ; (note: the first sector gets loaded by the BIOS, so ; subtract 1 here!) -NOF_LOAD_SECTORS equ 24 +NOF_LOAD_SECTORS equ 27 ; IN bx: begin of memory area to dump ; IN ax: number of words to dump |