sgikbd initial commit (based on a500kbd: https://github.com/jtsiomb/a500kbd)
[sgikbd] / fw / src / main.c
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"
12
13 enum {
14         KF_BRK = 1,
15         KF_EXT = 2,
16         KF_EXT1 = 4,
17
18         KF_CTRL         = 16,
19         KF_LAMIGA       = 32,
20         KF_RAMIGA       = 64
21 };
22 #define KF_TRANSIENT    0x0f
23 #define KF_STICKY               0xf0
24
25 #define RESET_WAIT 1000
26
27 static unsigned char led_state;
28
29 int main(void)
30 {
31         unsigned int keyflags = 0;
32         unsigned char c, keycode, prev_drvled = 0;
33         int press;
34
35         /* disable all pullups globally */
36         MCUCR |= 1 << PUD;
37
38         DDRD = 0;
39         PORTD = 0;
40         EIMSK = 0;      /* mask external interrupts */
41         EICRA = (1 << ISC11) | (1 << ISC01);    /* falling edge interrupts */
42
43         init_timer();
44
45         /* initialize the UART and enable interrupts */
46         init_serial(9600);
47         sei();
48
49         printf("PS/2 keyboard controller - John Tsiombikas <nuclear@member.fsf.org>\r\n");
50
51         EIMSK = (1 << INT0) | (1 << INT1);      /* enable ps/2 clock interrupt */
52
53         ps2setled(0);   /* start with all LEDs off */
54
55         for(;;) {
56                 while(!ps2pending()) {
57                         unsigned char drvled = PIND & ADRVLED_BIT;
58                         if(drvled != prev_drvled) {
59                                 prev_drvled = drvled;
60                                 if(drvled) {
61                                         led_state |= PS2LED_SCRLK;
62                                 } else {
63                                         led_state &= ~PS2LED_SCRLK;
64                                 }
65                                 ps2setled(led_state);
66                         }
67                 }
68
69                 c = ps2read();
70                 switch(c) {
71                 case 0xe0:      /* extended */
72                         keyflags |= KF_EXT;
73                         break;
74
75                 case 0xe1:      /* extended */
76                         keyflags |= KF_EXT1;
77                         break;
78
79                 case 0xf0:      /* break code */
80                         keyflags |= KF_BRK;
81                         break;
82
83                 default:
84                         press = !(keyflags & KF_BRK);
85
86                         keycode = 0xff;
87                         if(keyflags & KF_EXT) {
88                                 if(c < KEYMAP_EXT_SIZE) {
89                                         keycode = keymap_ext[(int)c];
90                                 }
91                         } else if(keyflags & KF_EXT1) {
92                         } else {
93                                 if(c < KEYMAP_NORMAL_SIZE) {
94                                         keycode = keymap_normal[(int)c];
95                                 }
96                         }
97
98                         switch(keycode) {
99                         case AMIKEY_CTRL:
100                                 if(press)
101                                         keyflags |= KF_CTRL;
102                                 else
103                                         keyflags &= ~KF_CTRL;
104                                 break;
105
106                         case AMIKEY_LAMI:
107                                 if(press)
108                                         keyflags |= KF_LAMIGA;
109                                 else
110                                         keyflags &= ~KF_LAMIGA;
111                                 break;
112
113                         case AMIKEY_RAMI:
114                                 if(press)
115                                         keyflags |= KF_RAMIGA;
116                                 else
117                                         keyflags &= ~KF_RAMIGA;
118                                 break;
119
120                         default:
121                                 break;
122                         }
123
124                         if((keyflags & (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) == (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) {
125                                 printf("CTRL - AMIGA - AMIGA!\r\n");
126                                 amikb_reset();
127
128                                 keyflags = 0;
129
130                                 reset_timer();
131                                 while(get_msec() < RESET_WAIT);
132                                 ps2clearbuf();
133
134                                 break;
135                         }
136
137                         if(keycode != 0xff) {
138                                 int press = ~keyflags & KF_BRK;
139                                 amikb_sendkey(keycode, press);
140                                 if(keycode == 0x62 && press) {
141                                         led_state ^= PS2LED_CAPSLK;
142                                         ps2setled(led_state);
143                                 }
144                                 /*printf("scancode %x -> [%s] amiga key %xh\r\n", (unsigned int)c, press ? "press" : "release", keycode);*/
145                         } else {
146                                 printf("PS/2 unknown command or keycode: %x\r\n", (unsigned int)c);
147                         }
148                         keyflags &= ~KF_TRANSIENT;
149                 }
150         }
151         return 0;
152 }