summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-11-14 06:52:00 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2014-02-11 02:07:51 (GMT)
commit7db61d5b9b7bf8660ddf859ecf73cf76f7ea0f03 (patch)
treef24d93e4cca6870165fe490d85f16749fb0ffaa8
parent3e450fcb06cce54097b30ceba6256aed91aa9d9b (diff)
downloadabc8000-7db61d5b9b7bf8660ddf859ecf73cf76f7ea0f03.zip
abc8000-7db61d5b9b7bf8660ddf859ecf73cf76f7ea0f03.tar.gz
abc8000-7db61d5b9b7bf8660ddf859ecf73cf76f7ea0f03.tar.bz2
abc8000-7db61d5b9b7bf8660ddf859ecf73cf76f7ea0f03.tar.xz
Make the keyboard driver work and actually do something useful
-rwxr-xr-xdata/sysrom/kbd/keymap.pl14
-rw-r--r--data/sysrom/kbd/se.key13
-rw-r--r--data/sysrom/keyboard.c87
-rw-r--r--data/sysrom/keyboard.h24
-rw-r--r--data/sysrom/sysstart.c17
5 files changed, 108 insertions, 47 deletions
diff --git a/data/sysrom/kbd/keymap.pl b/data/sysrom/kbd/keymap.pl
index a5f50af..69c5887 100755
--- a/data/sysrom/kbd/keymap.pl
+++ b/data/sysrom/kbd/keymap.pl
@@ -1,5 +1,7 @@
#!/usr/bin/perl
+use Encode;
+
for ($i = 0; $i < 256; $i++) {
$keytype[$i] = "KEY_IGNORE";
$keydata[$i] = [];
@@ -8,12 +10,15 @@ for ($i = 0; $i < 256; $i++) {
$max_nontriv_key = -1;
while (defined($line = <>)) {
- $line =~ s/^(|.*[^\+])\#.*$/\1/;
+ chomp $line;
+ $line =~ s/^(|.*?[^\+])\#.*$/\1/;
+
+ $line = Encode::decode_utf8($line);
- if ($line =~ /^([0-9a-f]+)\s+(\S+)\s+(.*)$/i) {
+ if ($line =~ /^([0-9a-f]+)\s+(\S+)(|\s+(.*))$/i) {
$key = hex $1;
$type = $2;
- $data = $3;
+ $data = $4;
$keytype[$key] = "KEY_\U$type";
@@ -28,7 +33,8 @@ while (defined($line = <>)) {
} elsif ($d =~ /^([0-9]+)$/) {
$d = $1 + 0;
} else {
- $d = ord $d;
+ printf STDERR "Key %02x: unknown string: $d\n", $key;
+ $d = 0;
}
push(@datan, $d);
}
diff --git a/data/sysrom/kbd/se.key b/data/sysrom/kbd/se.key
index 6ca952d..6f9e546 100644
--- a/data/sysrom/kbd/se.key
+++ b/data/sysrom/kbd/se.key
@@ -15,6 +15,7 @@
5f lock 0x01 # Scroll Lock
62 symbol 143 143 143 143 143 143 143 143 # Pause
+0e symbol +§ +½ +§ +½ +§ +½ +§ +½ # § ½
16 symbol +1 +! +1 +! +1 +! +1 +! # 1 !
1e symbol +2 +" 0 0 +@ +@ 0 0 # 2 " @
26 symbol +3 +# +3 +# +£ +£ +£ +£ # 3 # £
@@ -25,9 +26,10 @@
3e symbol +8 +( 27 27 +[ +[ 27 27 # 8 ( [
46 symbol +9 +) 29 29 +] +] 29 29 # 9 ) ]
45 symbol +0 += +0 += +} +} +} +} # 0 = }
-4e symbol + + +? 28 28 +\ +\ 28 28 # + ? \
+4e symbol ++ +? 28 28 +\ +\ 28 28 # + ? \
55 symbol +' +` +' +` +´ +` +´ +` # ' `
66 symbol 8 8 8 8 8 8 8 8 # Backspace
+
0d symbol 9 9 9 9 9 9 9 9 # Tab
15 sym_alpha +q +Q 17 17 +q +Q 17 17 # Q
1d sym_alpha +w +W 23 23 +w +W 23 23 # W
@@ -41,6 +43,7 @@
4d sym_alpha +p +P 16 16 +p +P 16 16 # P
54 sym_alpha_na +å +Å 29 29 +[ +{ 27 27 # Å [ {
5b sym_alpha_na +ü +Ü 30 30 +~ +^ 30 30 # ¨ ^ ~
+
14 lock 0x04 # Caps Lock
1c sym_alpha +a +A 1 1 +a +A 1 1 # A
1b sym_alpha +s +S 19 19 +s +S 19 19 # S
@@ -55,6 +58,7 @@
52 sym_alpha_na +ä +Ä 27 27 +' +" 27 27 # Ä ' "
53 symbol +' +* +' +* +' +* +' +* # ' *
5a symbol 13 13 13 13 13 13 13 13 # Enter
+
12 shift 0x01 # Left Shift
13 symbol +< +> 127 127 +| +| 127 127 # < > |
1a sym_alpha +z +Z 26 26 +z +Z 26 26 # Z
@@ -67,7 +71,8 @@
41 symbol +, +; +, +; +« +< +« +< # , ; <
49 symbol +. +: +. +: +» +> +» +> # . : >
4a symbol +- +_ 31 31 +/ +? +/ +? # - _ / ?
-51 shift 0x10 # Right Shift
+59 shift 0x10 # Right Shift
+
11 shift 0x02 # Left Ctrl
8b shift 0x08 # Left GUI
19 shift 0x04 # Left Alt
@@ -79,7 +84,7 @@
67 symbol 144 144 144 144 144 144 144 144 # Insert
6e symbol 146 146 146 146 146 146 146 146 # Home
-7d symbol 148 148 148 148 148 148 148 148 # Page Up
+6f symbol 148 148 148 148 148 148 148 148 # Page Up
64 symbol 145 145 145 145 145 145 145 145 # Delete
65 symbol 147 147 147 147 147 147 147 147 # End
6d symbol 149 149 149 149 149 149 149 149 # Page Down
@@ -107,7 +112,7 @@
71 symbol +. +, +. +, +. +, +. +, # KP . ,
# Special codes
-aa reset
+aa init
e0 reset
e1 reset
f0 break
diff --git a/data/sysrom/keyboard.c b/data/sysrom/keyboard.c
index c41555a..579579e 100644
--- a/data/sysrom/keyboard.c
+++ b/data/sysrom/keyboard.c
@@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
- * Copyright 2010 H. Peter Anvin - All Rights Reserved
+ * Copyright 2010-2011 H. Peter Anvin - All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -34,13 +34,15 @@ static const uint8_t kbd_reset[] =
{
0xff, /* Reset keyboard */
};
-static const uint8_t kbd_init[] =
+static uint8_t kbd_init[] =
{
0xf0, /* Set scan code set */
0x03, /* Scan code set 3 */
0xfa, /* Set all keys Make/Break/Repeat */
0xf3, /* Set repeat rate and delay */
0x00, /* 250 ms, 30 CPS */
+ 0xed, /* Write LEDs */
+ 0, /* LED value */
};
static uint8_t kbd_set_leds[] =
{
@@ -57,9 +59,13 @@ static uint8_t kbd_lock_state;
static uint8_t kbd_shift_keys;
static uint8_t kbd_shift_state;
-static bool kbd_need_leds;
static bool kbd_break_pfx;
+static inline void send_byte(uint8_t b)
+{
+ writeb(b, IO_KBD_DATA);
+}
+
static void keyboard_reset(void)
{
kbd_lock_state = KBD_NUM_LOCK;
@@ -67,13 +73,11 @@ static void keyboard_reset(void)
kbd_shift_state = 0;
- kbd_need_leds = false; /* Not yet */
kbd_break_pfx = false;
kbd_cmd_ptr = kbd_reset;
kbd_cmd_len = sizeof kbd_reset;
-
- writeb(*kbd_cmd_ptr, IO_KBD_DATA);
+ send_byte(*kbd_cmd_ptr);
}
void keyboard_init(void)
@@ -98,6 +102,7 @@ static void __attribute__((interrupt)) keyboard_irq(void)
uint8_t bucky;
uint8_t sym;
uint8_t type;
+ uint8_t next_head;
while (readb(IO_KBD_STATUS) & 1) {
scan = readb(IO_KBD_DATA);
@@ -107,12 +112,7 @@ static void __attribute__((interrupt)) keyboard_irq(void)
case 0xfa:
kbd_cmd_ptr++;
if (--kbd_cmd_len) {
- writeb(*kbd_cmd_ptr, IO_KBD_DATA);
- } else if (kbd_need_leds) {
- kbd_set_leds[1] = kbd_lock_state;
- kbd_cmd_ptr = kbd_set_leds;
- kbd_cmd_len = sizeof kbd_set_leds;
- writeb(*kbd_cmd_ptr, IO_KBD_DATA);
+ send_byte(*kbd_cmd_ptr);
}
break;
@@ -121,7 +121,7 @@ static void __attribute__((interrupt)) keyboard_irq(void)
break;
case 0xfe:
- writeb(*kbd_cmd_ptr, IO_KBD_DATA);
+ send_byte(*kbd_cmd_ptr);
break;
default:
@@ -133,12 +133,21 @@ static void __attribute__((interrupt)) keyboard_irq(void)
switch (type & 0x0f) {
case KEY_IGNORE:
default:
+ kbd_break_pfx = false;
break;
case KEY_RESET:
keyboard_reset();
break;
+ case KEY_INIT:
+ kbd_init[sizeof kbd_init-1] = kbd_lock_state;
+ kbd_cmd_ptr = kbd_init;
+ kbd_cmd_len = sizeof kbd_init;
+ send_byte(*kbd_cmd_ptr);
+ kbd_break_pfx = false;
+ break;
+
case KEY_BREAK:
kbd_break_pfx = true;
break;
@@ -152,6 +161,7 @@ static void __attribute__((interrupt)) keyboard_irq(void)
}
kbd_shift_state =
kbd_shift_keys | (kbd_shift_keys >> 4);
+ kbd_break_pfx = false;
break;
case KEY_LOCK:
@@ -164,27 +174,50 @@ static void __attribute__((interrupt)) keyboard_irq(void)
kbd_set_leds[1] = kbd_lock_state;
kbd_cmd_ptr = kbd_set_leds;
kbd_cmd_len = sizeof kbd_set_leds;
- writeb(*kbd_cmd_ptr, IO_KBD_DATA);
+ send_byte(*kbd_cmd_ptr);
}
+ kbd_break_pfx = false;
break;
case KEY_SYMBOL:
- bucky = kbd_shift_state & 7;
- if (kbd_lock_state & KBD_CAPS_LOCK) {
- uint8_t mask = (bucky & KBD_ALT_L) ? KEY_ALTALPHA : KEY_ALPHA;
- if (type & mask)
- bucky ^= KBD_SHIFT_L;
- }
- sym = key_data[scan][bucky];
- if (kbd_head != kbd_tail) {
- kbd_ringbuf[kbd_head].sym = sym;
- kbd_ringbuf[kbd_head].scan = scan;
- kbd_ringbuf[kbd_head].shift = kbd_shift_keys;
- kbd_ringbuf[kbd_head].lock = kbd_lock_state;
- kbd_head = (kbd_head + 1) % ELEMENTS(kbd_ringbuf);
+ if (!kbd_break_pfx) {
+ bucky = kbd_shift_state & 7;
+ if (kbd_lock_state & KBD_CAPS_LOCK) {
+ uint8_t mask = (bucky & KBD_ALT_L) ? KEY_ALTALPHA : KEY_ALPHA;
+ if (type & mask)
+ bucky ^= KBD_SHIFT_L;
+ }
+ sym = key_data[scan][bucky];
+ next_head = (kbd_head + 1) % ELEMENTS(kbd_ringbuf);
+ if (next_head != kbd_tail) {
+ kbd_ringbuf[kbd_head].sym = sym;
+ kbd_ringbuf[kbd_head].scan = scan;
+ kbd_ringbuf[kbd_head].shift = kbd_shift_keys;
+ kbd_ringbuf[kbd_head].lock = kbd_lock_state;
+ kbd_head = next_head;
+ }
}
+ kbd_break_pfx = false;
break;
}
}
}
}
+
+uint32_t get_key(void)
+{
+ uint32_t v = -1;
+ uint16_t status;
+
+ status = cpu_get_status();
+ cpu_set_spl(7);
+
+ if (kbd_head != kbd_tail) {
+ v = kbd_ringbuf[kbd_tail].v;
+ kbd_tail++;
+ }
+
+ cpu_set_status(status);
+
+ return v;
+}
diff --git a/data/sysrom/keyboard.h b/data/sysrom/keyboard.h
index 0ce8cd6..9b02223 100644
--- a/data/sysrom/keyboard.h
+++ b/data/sysrom/keyboard.h
@@ -17,10 +17,11 @@
#define KEY_IGNORE 0x00
#define KEY_RESET 0x01
-#define KEY_BREAK 0x02
-#define KEY_SHIFT 0x03
-#define KEY_LOCK 0x04
-#define KEY_SYMBOL 0x05
+#define KEY_INIT 0x02
+#define KEY_BREAK 0x03
+#define KEY_SHIFT 0x04
+#define KEY_LOCK 0x05
+#define KEY_SYMBOL 0x06
#define KEY_ALPHA 0x10 /* Key is sensitive to Caps Lock */
#define KEY_ALTALPHA 0x20 /* Key is sensitive to Caps Lock in Alt mode */
#define KEY_SYM_ALPHA (KEY_SYMBOL|KEY_ALPHA|KEY_ALTALPHA)
@@ -44,10 +45,17 @@ extern const uint8_t key_type[256];
extern const uint8_t key_data[][8];
struct key_stroke {
- uint8_t sym;
- uint8_t scan;
- uint8_t shift;
- uint8_t lock;
+ union {
+ struct {
+ uint8_t lock;
+ uint8_t shift;
+ uint8_t scan;
+ uint8_t sym;
+ };
+ uint32_t v;
+ };
};
+uint32_t get_key(void);
+
#endif /* SYSROM_KEYBOARD_H */
diff --git a/data/sysrom/sysstart.c b/data/sysrom/sysstart.c
index ff0beeb..02ad847 100644
--- a/data/sysrom/sysstart.c
+++ b/data/sysrom/sysstart.c
@@ -4,6 +4,7 @@
#include <ioreg.h>
#include <sys/cpu.h>
#include "sysrom.h"
+#include "keyboard.h"
/* We don't trust printf yet for conversion to ASCII */
static char *tohex(uint32_t v)
@@ -250,8 +251,6 @@ static void picture(void)
void sys_start(void)
{
- int i;
-
printf("Hello C code!\n");
printf("Hello C code again, 2^8 = %d\n", 256);
@@ -262,9 +261,19 @@ void sys_start(void)
//disk_boot();
syscon_init();
+ keyboard_init();
+
+ while (1) {
+ uint32_t c;
+ uint8_t cb;
- for (i = 0; i < 1000; i++)
- syscon_write(1, "Hello, World! ", 14);
+ do {
+ c = get_key();
+ } while (c == -1U);
+ cb = c;
+
+ syscon_write(1, &cb, 1);
+ }
monitor();
die();