summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-04 15:14:23 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-04 15:14:23 +0200
commit7099e089cdb78076032e16318c7886bf12b53d04 (patch)
tree2a6596b743056ef2362192ca7bc465db6827a2a5
parentc645abdb40763ff13cc31f7d8e66543f1fb744d1 (diff)
downloadabaos-7099e089cdb78076032e16318c7886bf12b53d04.tar.gz
abaos-7099e089cdb78076032e16318c7886bf12b53d04.tar.bz2
emitting mouse events now, printing them for now, later this will be
the text mode cursor
-rw-r--r--src/Makefile4
-rw-r--r--src/kernel.c34
-rw-r--r--src/keyboard.c3
-rw-r--r--src/keyboard.h36
-rw-r--r--src/mouse.c78
-rw-r--r--src/mouse.h28
-rw-r--r--src/stage1_functions.asm2
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