summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2011-06-19 16:35:31 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2011-06-19 16:35:31 (GMT)
commit97aff175b546b30dca7479e3fdfcd9e54bae2bdf (patch)
tree107cddf0089bce7a59d7a12195fa68f56553b977
parent6f1bcd18cc40ddfa698cebd588752dbfeb08869c (diff)
downloadabc8000-old-97aff175b546b30dca7479e3fdfcd9e54bae2bdf.zip
abc8000-old-97aff175b546b30dca7479e3fdfcd9e54bae2bdf.tar.gz
abc8000-old-97aff175b546b30dca7479e3fdfcd9e54bae2bdf.tar.bz2
abc8000-old-97aff175b546b30dca7479e3fdfcd9e54bae2bdf.tar.xz
sysrom: Add keyboard driver
Add keyboard driver to the sysrom code (not yet linked in.)
-rw-r--r--data/sysrom/Makefile16
-rwxr-xr-xdata/sysrom/kbd/keymap.pl63
-rw-r--r--data/sysrom/kbd/se.key116
-rw-r--r--data/sysrom/keyboard.c187
-rw-r--r--data/sysrom/keyboard.h46
5 files changed, 421 insertions, 7 deletions
diff --git a/data/sysrom/Makefile b/data/sysrom/Makefile
index 09f7f98..21641b1 100644
--- a/data/sysrom/Makefile
+++ b/data/sysrom/Makefile
@@ -10,7 +10,7 @@ RANLIB = m68k-none-elf-ranlib
READELF = m68k-none-elf-readelf
PERL = perl
-INCLUDE = -I./include -I./fat/src
+INCLUDE = -I. -I./include -I./fat/src
CCWARN = -W -Wall -Wwrite-strings -Wmissing-prototypes
CFLAGS = -m68000 -O2 -fomit-frame-pointer -ffreestanding \
@@ -26,10 +26,9 @@ SYSOBJS = $(patsubst %.asm,%.o,$(wildcard *.asm)) \
$(patsubst %.c,%.o,$(wildcard *.c))
ABCOBJS = $(patsubst %.asm,%.o,$(wildcard abc/*.asm)) \
$(patsubst %.c,%.o,$(wildcard abc/*.c))
-
LIBOBJS = $(patsubst %.asm,%.o,$(wildcard lib/*.asm)) \
$(patsubst %.c,%.o,$(wildcard lib/*.c fat/src/*.c)) \
- font/sysfont.o
+ font/sysfont.o kbd/keymap.o
LIB = libsys.a
@@ -39,6 +38,10 @@ FONT = 8x16-abc-l1.bdf
font/sysfont.c: font/$(FONT) font/bdf2c.pl
$(PERL) font/bdf2c.pl __sysfont 8 16 < $< > $@ || ( rm -f $@ ; false )
+KEYMAP = se.key
+kbd/keymap.c: kbd/$(KEYMAP) kbd/keymap.pl
+ $(PERL) kbd/keymap.pl $< > $@ || ( rm -f $@ ; false )
+
sysrom.bin: sysrom.elf
$(OBJCOPY) -O binary $< $@
$(PERL) padto.pl $@ 512
@@ -83,11 +86,10 @@ MAKEDEPS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d
$(OBJCOPY) -O binary $< $@
clean:
- for d in . abc font lib fat/src; do \
+ for d in . abc font kbd lib fat/src; do \
rm -f $$d/*.o $$d/*.i $$d/*.s $$d/*.bin $$d/*.map \
$$d/*.sys $$d/*.shr $$d/*.elf $$d/*.a $$d/.*.d ; \
done
- rm -f font/sysfont.c
-
--include .*.d font/.*.d lib/.*.d fat/src/.*.d
+ rm -f font/*.c kbd/*.c
+-include .*.d font/.*.d kbd/.*.d lib/.*.d fat/src/.*.d
diff --git a/data/sysrom/kbd/keymap.pl b/data/sysrom/kbd/keymap.pl
new file mode 100755
index 0000000..a5f50af
--- /dev/null
+++ b/data/sysrom/kbd/keymap.pl
@@ -0,0 +1,63 @@
+#!/usr/bin/perl
+
+for ($i = 0; $i < 256; $i++) {
+ $keytype[$i] = "KEY_IGNORE";
+ $keydata[$i] = [];
+}
+
+$max_nontriv_key = -1;
+
+while (defined($line = <>)) {
+ $line =~ s/^(|.*[^\+])\#.*$/\1/;
+
+ if ($line =~ /^([0-9a-f]+)\s+(\S+)\s+(.*)$/i) {
+ $key = hex $1;
+ $type = $2;
+ $data = $3;
+
+ $keytype[$key] = "KEY_\U$type";
+
+ @datal = split(/\s+/, $data);
+ @datan = ();
+
+ foreach $d (@datal) {
+ if ($d =~ /^(0|)x([0-9a-f]{1,2})$/i ) {
+ $d = hex $2;
+ } elsif ($d =~ /^\+(.)$/) {
+ $d = ord $1;
+ } elsif ($d =~ /^([0-9]+)$/) {
+ $d = $1 + 0;
+ } else {
+ $d = ord $d;
+ }
+ push(@datan, $d);
+ }
+
+ $keydata[$key] = [@datan];
+ if (scalar(@datan) && $key >= $max_nontriv_key) {
+ $max_nontriv_key = $key;
+ }
+ }
+}
+
+print "#include \"keyboard.h\"\n\n";
+
+print "const uint8_t key_type[256] = {\n";
+for ($i = 0; $i < 256; $i++) {
+ printf "\t/* 0x%02x */ %s,\n", $i, $keytype[$i];
+}
+print "};\n\n";
+
+printf "const uint8_t key_data[%d][8] = {\n", $max_nontriv_key+1;
+for ($i = 0; $i <= $max_nontriv_key; $i++) {
+ printf "\t/* 0x%02x */ ", $i;
+ $c = '{';
+ @datan = @{$keydata[$i]};
+ for ($j = 0; $j < 8; $j++) {
+ $d = shift(@datan);
+ printf("%s0x%02x", $c, $d);
+ $c = ',';
+ }
+ print "},\n";
+}
+print "};\n";
diff --git a/data/sysrom/kbd/se.key b/data/sysrom/kbd/se.key
new file mode 100644
index 0000000..6ca952d
--- /dev/null
+++ b/data/sysrom/kbd/se.key
@@ -0,0 +1,116 @@
+08 symbol 27 27 27 27 27 27 27 27 # Escape
+07 symbol 128 128 128 128 128 128 128 128 # F1
+0f symbol 129 129 129 129 129 129 129 129 # F2
+17 symbol 130 130 130 130 130 130 130 130 # F3
+1f symbol 131 131 131 131 131 131 131 131 # F4
+27 symbol 132 132 132 132 132 132 132 132 # F5
+2f symbol 133 133 133 133 133 133 133 133 # F6
+37 symbol 134 134 134 134 134 134 134 134 # F7
+3f symbol 135 135 135 135 135 135 135 135 # F8
+47 symbol 136 136 136 136 136 136 136 136 # F9
+4f symbol 137 137 137 137 137 137 137 137 # F10
+56 symbol 138 138 138 138 138 138 138 138 # F11
+5e symbol 139 139 139 139 139 139 139 139 # F12
+57 symbol 141 141 141 141 141 141 141 141 # Print Screen/SysRq
+5f lock 0x01 # Scroll Lock
+62 symbol 143 143 143 143 143 143 143 143 # Pause
+
+16 symbol +1 +! +1 +! +1 +! +1 +! # 1 !
+1e symbol +2 +" 0 0 +@ +@ 0 0 # 2 " @
+26 symbol +3 +# +3 +# +£ +£ +£ +£ # 3 # £
+25 symbol +4 +¤ +4 +¤ +$ +$ +$ +$ # 4 ¤ $
+2e symbol +5 +% +5 +% +5 +% +5 +% # 5 %
+36 symbol +6 +& +6 +& +^ +^ +^ +^ # 6 & (^)
+3d symbol +7 +/ +7 +/ +{ +{ +{ +{ # 7 / {
+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 # + ? \
+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
+24 sym_alpha +e +E 5 5 +e +E 5 5 # E
+2d sym_alpha +r +R 18 18 +r +R 18 18 # R
+2c sym_alpha +t +T 20 20 +t +T 20 20 # T
+35 sym_alpha +y +Y 25 25 +y +Y 25 25 # Y
+3c sym_alpha +u +U 21 21 +u +U 21 21 # U
+43 sym_alpha +i +I 9 9 +i +I 9 9 # I
+44 sym_alpha +o +O 15 15 +o +O 15 15 # O
+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
+23 sym_alpha +d +D 4 4 +d +D 4 4 # D
+2b sym_alpha +f +F 6 6 +f +F 6 6 # F
+34 sym_alpha +g +G 7 7 +g +G 7 7 # G
+33 sym_alpha +h +H 8 8 +h +H 8 8 # H
+3b sym_alpha +j +J 10 10 +j +J 10 10 # J
+42 sym_alpha +k +K 11 11 +k +K 11 11 # K
+4b sym_alpha +l +L 12 12 +l +L 12 12 # L
+4c sym_alpha_na +ö +Ö 28 28 +: +; 28 28 # Ö ; :
+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
+22 sym_alpha +x +X 24 24 +x +X 24 24 # X
+21 sym_alpha +c +C 3 3 +c +C 3 3 # C
+2a sym_alpha +v +V 22 22 +v +V 22 22 # V
+32 sym_alpha +b +B 2 2 +b +B 2 2 # B
+31 sym_alpha +n +N 14 14 +n +N 14 14 # N
+3a sym_alpha +m +M 13 13 +m +M 13 13 # M
+41 symbol +, +; +, +; +« +< +« +< # , ; <
+49 symbol +. +: +. +: +» +> +» +> # . : >
+4a symbol +- +_ 31 31 +/ +? +/ +? # - _ / ?
+51 shift 0x10 # Right Shift
+11 shift 0x02 # Left Ctrl
+8b shift 0x08 # Left GUI
+19 shift 0x04 # Left Alt
+29 symbol 32 32 0 0 160 160 0 0 # Space
+39 shift 0x40 # Right Alt
+8c shift 0x80 # Right GUI
+8d ignore # Right Menu
+58 shift 0x20 # Right Ctrl
+
+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
+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
+63 symbol 152 152 152 152 152 152 152 152 # Up
+61 symbol 154 154 154 154 154 154 154 154 # Left
+60 symbol 158 158 158 158 158 158 158 158 # Down
+6a symbol 156 156 156 156 156 156 156 156 # Right
+
+76 lock 0x02 # Num Lock
+77 symbol +/ +/ +/ +/ +/ +/ +/ +/ # KP /
+7e symbol +* +* +* +* +* +* +* +* # KP *
+84 symbol +- +- +- +- +- +- +- +- # KP -
+6c symbol +7 +7 +7 +7 +7 +7 +7 +7 # KP 7
+75 symbol +8 +8 +8 +8 +8 +8 +8 +8 # KP 8
+7d symbol +9 +9 +9 +9 +9 +9 +9 +9 # KP 9
+7c symbol ++ ++ ++ ++ ++ ++ ++ ++ # KP +
+6b symbol +4 +4 +4 +4 +4 +4 +4 +4 # KP 4
+73 symbol +5 +5 +5 +5 +5 +5 +5 +5 # KP 5
+74 symbol +6 +6 +6 +6 +6 +6 +6 +6 # KP 6
+69 symbol +1 +1 +1 +1 +1 +1 +1 +1 # KP 1
+72 symbol +2 +2 +2 +2 +2 +2 +2 +2 # KP 2
+7a symbol +3 +3 +3 +3 +3 +3 +3 +3 # KP 3
+79 symbol 13 13 13 13 13 13 13 13 # KP Enter
+70 symbol +0 +0 +0 +0 +0 +0 +0 +0 # KP 0
+71 symbol +. +, +. +, +. +, +. +, # KP . ,
+
+# Special codes
+aa reset
+e0 reset
+e1 reset
+f0 break
+fa reset
+fe reset
+ff reset
diff --git a/data/sysrom/keyboard.c b/data/sysrom/keyboard.c
new file mode 100644
index 0000000..7251009
--- /dev/null
+++ b/data/sysrom/keyboard.c
@@ -0,0 +1,187 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * Copyright 2010 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
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * keyboard.c
+ *
+ * ABC8000 keyboard driver
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <ioreg.h>
+#include <sys/cpu.h>
+#include "sysrom.h"
+#include "keyboard.h"
+
+static void keyboard_irq(void);
+
+static uint16_t kbd_ringbuf[256], kbd_head, kbd_tail;
+
+static const uint8_t kbd_reset[] =
+{
+ 0xff, /* Reset keyboard */
+};
+static const 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 */
+};
+static uint8_t kbd_set_leds[] =
+{
+ 0xed, /* Write LEDs */
+ 0, /* LED value */
+};
+
+static const uint8_t *kbd_cmd_ptr;
+static uint16_t kbd_cmd_len;
+
+static uint8_t kbd_lock_keys;
+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 void keyboard_reset(void)
+{
+ kbd_lock_state = KBD_NUM_LOCK;
+ kbd_lock_keys = 0;
+
+ 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);
+}
+
+void keyboard_init(void)
+{
+ kbd_head = 0;
+ kbd_tail = 255;
+
+ __ivt[0x40] = keyboard_irq;
+
+ /* Enable the keyboard receive interrupt */
+ *IO_MFP_IERB |= 0x01;
+ *IO_MFP_IMRB |= 0x01;
+
+ /* Send reset to keyboard */
+ keyboard_reset();
+}
+
+static void __attribute__((interrupt)) keyboard_irq(void)
+{
+ uint8_t scan;
+ uint8_t data;
+ uint8_t bucky;
+ uint8_t sym;
+ uint8_t type;
+
+ while (readb(IO_KBD_STATUS) & 1) {
+ scan = readb(IO_KBD_DATA);
+
+ if (kbd_cmd_len) {
+ switch (scan) {
+ 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);
+ }
+ break;
+
+ case 0xaa:
+ keyboard_reset();
+ break;
+
+ case 0xfe:
+ writeb(*kbd_cmd_ptr, IO_KBD_DATA);
+ break;
+
+ default:
+ break; /* Ignore stray codes */
+ }
+ } else {
+ type = key_type[scan];
+
+ switch (type & 0x0f) {
+ case KEY_IGNORE:
+ default:
+ break;
+
+ case KEY_RESET:
+ keyboard_reset();
+ break;
+
+ case KEY_BREAK:
+ kbd_break_pfx = true;
+ break;
+
+ case KEY_SHIFT:
+ data = key_data[scan][0];
+ if (kbd_break_pfx) {
+ kbd_shift_keys &= ~data;
+ } else {
+ kbd_shift_keys |= data;
+ }
+ kbd_shift_state =
+ kbd_shift_keys | (kbd_shift_keys >> 4);
+ break;
+
+ case KEY_LOCK:
+ if (kbd_break_pfx) {
+ kbd_lock_keys &= ~data;
+ } else if (!(kbd_lock_keys & data)) {
+ kbd_lock_keys |= data;
+ kbd_lock_state ^= data;
+ 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);
+ }
+ break;
+
+ case KEY_SYMBOL:
+ bucky = kbd_shift_state & 7;
+ if (bucky & KBD_ALT_L) {
+ if (type & KEY_ALTALPHA)
+ bucky ^= KBD_SHIFT_L;
+ } else {
+ if (type & KEY_ALPHA)
+ bucky ^= KBD_SHIFT_L;
+ }
+ sym = key_data[scan][bucky];
+ if (kbd_head != kbd_tail) {
+ kbd_ringbuf[kbd_head] = sym;
+ kbd_head = (kbd_head + 1) % sizeof kbd_ringbuf;
+ }
+ break;
+ }
+ }
+ }
+}
diff --git a/data/sysrom/keyboard.h b/data/sysrom/keyboard.h
new file mode 100644
index 0000000..4968c61
--- /dev/null
+++ b/data/sysrom/keyboard.h
@@ -0,0 +1,46 @@
+/* ----------------------------------------------------------------------- *
+ *
+ * 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
+ * the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston MA 02110-1301, USA; either version 2 of the License, or
+ * (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef SYSROM_KEYBOARD_H
+#define SYSROM_KEYBOARD_H
+
+#include <inttypes.h>
+
+#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_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)
+#define KEY_SYM_ALPHA_NA (KEY_SYMBOL|KEY_ALPHA)
+#define KEY_SYM_ALPHA_AO (KEY_SYMBOL|KEY_ALTALPHA)
+
+#define KBD_SCROLL_LOCK 0x01
+#define KBD_NUM_LOCK 0x02
+#define KBD_CAPS_LOCK 0x04
+
+#define KBD_SHIFT_L 0x01
+#define KBD_SHIFT_R 0x10
+#define KBD_CTRL_L 0x02
+#define KBD_CTRL_R 0x20
+#define KBD_ALT_L 0x04
+#define KBD_ALR_R 0x40
+#define KBD_GUI_L 0x08
+#define KBD_GUI_R 0x80
+
+extern const uint8_t key_type[256];
+extern const uint8_t key_data[][8];
+
+#endif /* SYSROM_KEYBOARD_H */