a500kbd

view src/main.c @ 3:31a1f0b53d98

- scroll lock now acts as caps lock - the scroll-lock light indicates drive activity
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 18 Oct 2017 08:20:58 +0300
parents a4fd9c5a6655
children
line source
1 #include <stdio.h>
2 #include <ctype.h>
3 #include <avr/io.h>
4 #include <avr/interrupt.h>
5 #include <util/delay.h>
6 #include "serial.h"
7 #include "scantbl.h"
8 #include "ps2kbd.h"
9 #include "amigakb.h"
10 #include "defs.h"
11 #include "timer.h"
13 enum {
14 KF_BRK = 1,
15 KF_EXT = 2,
16 KF_EXT1 = 4,
18 KF_CTRL = 16,
19 KF_LAMIGA = 32,
20 KF_RAMIGA = 64
21 };
22 #define KF_TRANSIENT 0x0f
23 #define KF_STICKY 0xf0
25 static unsigned char led_state;
27 int main(void)
28 {
29 unsigned int keyflags = 0;
30 unsigned char c, keycode, prev_drvled = 0;
31 int press;
33 /* disable all pullups globally */
34 MCUCR |= 1 << PUD;
36 DDRD = 0;
37 PORTD = 0;
38 EIMSK = 0; /* mask external interrupts */
39 EICRA = (1 << ISC11) | (1 << ISC01); /* falling edge interrupts */
41 init_timer();
43 /* initialize the UART and enable interrupts */
44 init_serial(9600);
45 sei();
47 printf("PS/2 keyboard controller - John Tsiombikas <nuclear@member.fsf.org>\r\n");
49 EIMSK = (1 << INT0) | (1 << INT1); /* enable ps/2 clock interrupt */
51 ps2setled(0); /* start with all LEDs off */
53 for(;;) {
54 while(!ps2pending()) {
55 unsigned char drvled = PIND & ADRVLED_BIT;
56 if(drvled != prev_drvled) {
57 prev_drvled = drvled;
58 if(drvled) {
59 led_state |= PS2LED_SCRLK;
60 } else {
61 led_state &= ~PS2LED_SCRLK;
62 }
63 ps2setled(led_state);
64 }
65 }
67 c = ps2read();
68 switch(c) {
69 case 0xe0: /* extended */
70 keyflags |= KF_EXT;
71 break;
73 case 0xe1: /* extended */
74 keyflags |= KF_EXT1;
75 break;
77 case 0xf0: /* break code */
78 keyflags |= KF_BRK;
79 break;
81 default:
82 press = !(keyflags & KF_BRK);
84 keycode = 0xff;
85 if(keyflags & KF_EXT) {
86 if(c < KEYMAP_EXT_SIZE) {
87 keycode = keymap_ext[(int)c];
88 }
89 } else if(keyflags & KF_EXT1) {
90 } else {
91 if(c < KEYMAP_NORMAL_SIZE) {
92 keycode = keymap_normal[(int)c];
93 }
94 }
96 switch(keycode) {
97 case AMIKEY_CTRL:
98 if(press)
99 keyflags |= KF_CTRL;
100 else
101 keyflags &= ~KF_CTRL;
102 break;
104 case AMIKEY_LAMI:
105 if(press)
106 keyflags |= KF_LAMIGA;
107 else
108 keyflags &= ~KF_LAMIGA;
109 break;
111 case AMIKEY_RAMI:
112 if(press)
113 keyflags |= KF_RAMIGA;
114 else
115 keyflags &= ~KF_RAMIGA;
116 break;
118 default:
119 break;
120 }
122 if((keyflags & (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) == (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) {
123 printf("CTRL - AMIGA - AMIGA!\r\n");
124 amikb_reset();
125 }
127 if(keycode != 0xff) {
128 int press = ~keyflags & KF_BRK;
129 amikb_sendkey(keycode, press);
130 if(keycode == 0x62 && press) {
131 led_state ^= PS2LED_CAPSLK;
132 ps2setled(led_state);
133 }
134 /*printf("scancode %x -> [%s] amiga key %xh\r\n", (unsigned int)c, press ? "press" : "release", keycode);*/
135 } else {
136 printf("PS/2 unknown command or keycode: %x\r\n", (unsigned int)c);
137 }
138 keyflags &= ~KF_TRANSIENT;
139 }
140 }
141 return 0;
142 }