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