a500kbd

changeset 2:a4fd9c5a6655

first working version
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 17 Oct 2017 15:25:33 +0300
parents 3228a731d4db
children 31a1f0b53d98
files Makefile src/amigakb.c src/amigakb.h src/defs.h src/main.c src/ps2kbd.c src/ps2kbd.h src/scantbl.h src/serial.c src/timer.c src/timer.h
diffstat 11 files changed, 436 insertions(+), 149 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Sat Oct 14 07:23:47 2017 +0300
     1.2 +++ b/Makefile	Tue Oct 17 15:25:33 2017 +0300
     1.3 @@ -10,7 +10,7 @@
     1.4  CC = avr-gcc
     1.5  OBJCOPY = avr-objcopy
     1.6  
     1.7 -CFLAGS = -Os -pedantic -Wall -mmcu=$(mcu_gcc) -DXTAL=14745600
     1.8 +CFLAGS = -Os -pedantic -Wall -mmcu=$(mcu_gcc) -DF_CPU=14745600
     1.9  LDFLAGS = -Wl,-Map,$(bin).map -mmcu=$(mcu_gcc) -lprintf_min
    1.10  
    1.11  .PHONY: all
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/src/amigakb.c	Tue Oct 17 15:25:33 2017 +0300
     2.3 @@ -0,0 +1,124 @@
     2.4 +#include <stdio.h>
     2.5 +#include <avr/io.h>
     2.6 +#include <avr/interrupt.h>
     2.7 +#include <util/delay.h>
     2.8 +#include "amigakb.h"
     2.9 +#include "defs.h"
    2.10 +#include "timer.h"
    2.11 +
    2.12 +#define TIMEOUT_MSEC	143
    2.13 +
    2.14 +static void resync(void);
    2.15 +
    2.16 +void amikb_sendkey(unsigned char keycode, int press)
    2.17 +{
    2.18 +	int i;
    2.19 +	static unsigned char prev_keycode = 0xff;
    2.20 +
    2.21 +	/* keycode bit transfer order: 6 5 4 3 2 1 0 7 (7 is pressed flag) */
    2.22 +	keycode = (keycode << 1) | (~press & 1);
    2.23 +	if(keycode == prev_keycode) return;
    2.24 +	prev_keycode = keycode;
    2.25 +
    2.26 +	/* make sure we don't pulse the lines while grabbing control
    2.27 +	 * by first reinstating the pullups before changing direction
    2.28 +	 */
    2.29 +	PORTD |= ACLK_BIT | ADATA_BIT;
    2.30 +	DDRD |= ACLK_BIT | ADATA_BIT;
    2.31 +
    2.32 +	/* pulse the data line and wait for about 100us */
    2.33 +	PORTD &= ~ADATA_BIT;
    2.34 +	_delay_us(20);
    2.35 +	PORTD |= ADATA_BIT;
    2.36 +	_delay_us(100);
    2.37 +
    2.38 +	for(i=0; i<8; i++) {
    2.39 +		/* data line is inverted */
    2.40 +		if(keycode & 0x80) {
    2.41 +			PORTD &= ~ADATA_BIT;
    2.42 +		} else {
    2.43 +			PORTD |= ADATA_BIT;
    2.44 +		}
    2.45 +		keycode <<= 1;
    2.46 +		_delay_us(20);
    2.47 +		/* pulse the clock */
    2.48 +		cli();
    2.49 +		PORTD &= ~ACLK_BIT;
    2.50 +		EIFR |= (1 << INTF1);
    2.51 +		sei();
    2.52 +		_delay_us(20);
    2.53 +		PORTD |= ACLK_BIT;
    2.54 +		_delay_us(20);
    2.55 +	}
    2.56 +
    2.57 +	/* similarly tristate first, then drop the pullups */
    2.58 +	DDRD &= ~(ACLK_BIT | ADATA_BIT);
    2.59 +	PORTD &= ~(ACLK_BIT | ADATA_BIT);
    2.60 +
    2.61 +	/* wait for ack */
    2.62 +	reset_timer();
    2.63 +	while(PIND & ADATA_BIT) {
    2.64 +		if(get_msec() >= TIMEOUT_MSEC) {
    2.65 +			resync();
    2.66 +			break;
    2.67 +		}
    2.68 +	}
    2.69 +}
    2.70 +
    2.71 +void amikb_reset(void)
    2.72 +{
    2.73 +	cli();
    2.74 +	PORTD &= ~ARST_BIT;
    2.75 +	DDRD |= ARST_BIT;
    2.76 +	_delay_ms(10);
    2.77 +	PORTD |= ARST_BIT;
    2.78 +	DDRD &= ~ARST_BIT;
    2.79 +	sei();
    2.80 +}
    2.81 +
    2.82 +static void resync(void)
    2.83 +{
    2.84 +	PORTD |= ACLK_BIT | ADATA_BIT;
    2.85 +	printf("lost sync\r\n");
    2.86 +
    2.87 +	for(;;) {
    2.88 +		cli();
    2.89 +		DDRD |= ACLK_BIT | ADATA_BIT;
    2.90 +
    2.91 +		PORTD &= ~ACLK_BIT;
    2.92 +		EIFR |= (1 << INTF1);	/* clear interrupt raised by the previous line */
    2.93 +		sei();
    2.94 +		_delay_us(20);
    2.95 +		PORTD |= ACLK_BIT;
    2.96 +
    2.97 +		DDRD &= ~(ACLK_BIT | ADATA_BIT);
    2.98 +
    2.99 +		reset_timer();
   2.100 +		while(get_msec() < TIMEOUT_MSEC) {
   2.101 +			if(!(PIND & ADATA_BIT)) {
   2.102 +				return;
   2.103 +			}
   2.104 +		}
   2.105 +	}
   2.106 +}
   2.107 +
   2.108 +static void handle_cmd(unsigned char cmd)
   2.109 +{
   2.110 +	printf("amikbd got cmd: %x\r\n", (unsigned int)cmd);
   2.111 +}
   2.112 +
   2.113 +ISR(INT1_vect)
   2.114 +{
   2.115 +	static unsigned char value;
   2.116 +	static int nbits;
   2.117 +
   2.118 +	value <<= 1;
   2.119 +	if(PIND & ADATA_BIT) {
   2.120 +		value |= 1;
   2.121 +	}
   2.122 +	if(++nbits >= 8) {
   2.123 +		handle_cmd(value);
   2.124 +		nbits = 0;
   2.125 +		value = 0;
   2.126 +	}
   2.127 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/src/amigakb.h	Tue Oct 17 15:25:33 2017 +0300
     3.3 @@ -0,0 +1,7 @@
     3.4 +#ifndef AMIGAKB_H_
     3.5 +#define AMIGAKB_H_
     3.6 +
     3.7 +void amikb_sendkey(unsigned char keycode, int press);
     3.8 +void amikb_reset(void);
     3.9 +
    3.10 +#endif	/* AMIGAKB_H_ */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/defs.h	Tue Oct 17 15:25:33 2017 +0300
     4.3 @@ -0,0 +1,29 @@
     4.4 +#ifndef DEFS_H_
     4.5 +#define DEFS_H_
     4.6 +
     4.7 +#include <avr/io.h>
     4.8 +
     4.9 +/* pin assignments:
    4.10 + * D2	PS/2 clock (INT0)
    4.11 + * D3	amikbd clock (INT1)
    4.12 + * D4	PS/2 data
    4.13 + * D5	amikbd data
    4.14 + * D6	amiga reset
    4.15 + * D7	amiga drvled in
    4.16 + */
    4.17 +
    4.18 +#define PCLK	2
    4.19 +#define ACLK	3
    4.20 +#define PDATA	4
    4.21 +#define ADATA	5
    4.22 +#define ARST	6
    4.23 +#define ADRVLED	7
    4.24 +
    4.25 +#define PCLK_BIT	(1 << PCLK)
    4.26 +#define ACLK_BIT	(1 << ACLK)
    4.27 +#define PDATA_BIT	(1 << PDATA)
    4.28 +#define ADATA_BIT	(1 << ADATA)
    4.29 +#define ARST_BIT	(1 << ARST)
    4.30 +#define ADRVLED_BIT	(1 << ADRVLED)
    4.31 +
    4.32 +#endif	/* DEFS_H_ */
     5.1 --- a/src/main.c	Sat Oct 14 07:23:47 2017 +0300
     5.2 +++ b/src/main.c	Tue Oct 17 15:25:33 2017 +0300
     5.3 @@ -1,64 +1,50 @@
     5.4 -#define F_CPU	XTAL
     5.5  #include <stdio.h>
     5.6  #include <ctype.h>
     5.7  #include <avr/io.h>
     5.8  #include <avr/interrupt.h>
     5.9  #include <util/delay.h>
    5.10 -#include <util/parity.h>
    5.11  #include "serial.h"
    5.12  #include "scantbl.h"
    5.13 -
    5.14 -/* pin assignments:
    5.15 - * B0	PS/2 data
    5.16 - * D2	PS/2 clock (INT0)
    5.17 - * B1	KBD data
    5.18 - * D3	KBD clock (INT1)
    5.19 - */
    5.20 -
    5.21 -#define BIT_DATA	1
    5.22 -#define BIT_CLK		2
    5.23 -
    5.24 -#define PS2LOW(bit) do { DDRB |= (bit); PORTB &= ~(bit); } while(0)
    5.25 -#define PS2HIGH(bit) do { DDRB |= (bit); PORTB |= (bit); } while(0)
    5.26 -#define PS2REL(bit) do { DDRB &= ~(bit); PORTB &= ~(bit); } while(0)
    5.27 -
    5.28 -void ps2write(unsigned char c);
    5.29 -unsigned char ps2read(void);
    5.30 -int ps2pending(void);
    5.31 -
    5.32 -#define BUF_SZ	16
    5.33 -#define BUF_IDX_MASK	(BUF_SZ - 1)
    5.34 -#define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK)
    5.35 -static volatile unsigned char keybuf[BUF_SZ];
    5.36 -static volatile unsigned char key_rd, key_wr;
    5.37 -
    5.38 -static volatile int sending;
    5.39 +#include "ps2kbd.h"
    5.40 +#include "amigakb.h"
    5.41 +#include "defs.h"
    5.42 +#include "timer.h"
    5.43  
    5.44  enum {
    5.45  	KF_BRK = 1,
    5.46  	KF_EXT = 2,
    5.47  	KF_EXT1 = 4,
    5.48 +
    5.49 +	KF_CTRL		= 16,
    5.50 +	KF_LAMIGA	= 32,
    5.51 +	KF_RAMIGA	= 64
    5.52  };
    5.53 +#define KF_TRANSIENT	0x0f
    5.54 +#define KF_STICKY		0xf0
    5.55  
    5.56  int main(void)
    5.57  {
    5.58  	unsigned int keyflags = 0;
    5.59 -	int keycode;
    5.60 +	unsigned char keycode;
    5.61 +	int press;
    5.62  
    5.63 -	DDRB = 0;
    5.64 +	/* disable all pullups globally */
    5.65 +	MCUCR |= 1 << PUD;
    5.66 +
    5.67  	DDRD = 0;
    5.68 -	PORTB = 0;
    5.69  	PORTD = 0;
    5.70  	EIMSK = 0;	/* mask external interrupts */
    5.71  	EICRA = (1 << ISC11) | (1 << ISC01);	/* falling edge interrupts */
    5.72  
    5.73 +	init_timer();
    5.74 +
    5.75  	/* initialize the UART and enable interrupts */
    5.76  	init_serial(9600);
    5.77  	sei();
    5.78  
    5.79  	printf("PS/2 keyboard controller - John Tsiombikas <nuclear@member.fsf.org>\r\n");
    5.80  
    5.81 -	EIMSK = (1 << INT0);	/* enable ps/2 clock interrupt */
    5.82 +	EIMSK = (1 << INT0) | (1 << INT1);	/* enable ps/2 clock interrupt */
    5.83  
    5.84  	for(;;) {
    5.85  		unsigned char c = ps2read();
    5.86 @@ -76,7 +62,9 @@
    5.87  			break;
    5.88  
    5.89  		default:
    5.90 -			keycode = 0;
    5.91 +			press = !(keyflags & KF_BRK);
    5.92 +
    5.93 +			keycode = 0xff;
    5.94  			if(keyflags & KF_EXT) {
    5.95  				printf("ext ");
    5.96  				if(c < KEYMAP_EXT_SIZE) {
    5.97 @@ -90,94 +78,48 @@
    5.98  				}
    5.99  			}
   5.100  
   5.101 -			if(keycode >= 256) {
   5.102 -				/*printf("%s: %s (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", skeystr[keycode - 256], (unsigned int)c);*/
   5.103 -				printf("%s: key %xh (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", keycode, (unsigned int)c);
   5.104 -			} else if(isprint(keycode)) {
   5.105 -				printf("%s: %c (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", (char)keycode, (unsigned int)c);
   5.106 -			} else if(keycode > 0) {
   5.107 -				printf("%s: key %xh (scancode: %x)\r\n", keyflags & KF_BRK ? "release" : "press", keycode, (unsigned int)c);
   5.108 +			switch(keycode) {
   5.109 +			case AMIKEY_CTRL:
   5.110 +				if(press)
   5.111 +					keyflags |= KF_CTRL;
   5.112 +				else
   5.113 +					keyflags &= ~KF_CTRL;
   5.114 +				break;
   5.115 +
   5.116 +			case AMIKEY_LAMI:
   5.117 +				if(press)
   5.118 +					keyflags |= KF_LAMIGA;
   5.119 +				else
   5.120 +					keyflags &= ~KF_LAMIGA;
   5.121 +				break;
   5.122 +
   5.123 +			case AMIKEY_RAMI:
   5.124 +				if(press)
   5.125 +					keyflags |= KF_RAMIGA;
   5.126 +				else
   5.127 +					keyflags &= ~KF_RAMIGA;
   5.128 +				break;
   5.129 +
   5.130 +			default:
   5.131 +				break;
   5.132 +			}
   5.133 +
   5.134 +			if((keyflags & (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) == (KF_CTRL | KF_RAMIGA | KF_LAMIGA)) {
   5.135 +				printf("CTRL - AMIGA - AMIGA!\r\n");
   5.136 +				amikb_reset();
   5.137 +			}
   5.138 +
   5.139 +			printf("scancode %x -> ", (unsigned int)c);
   5.140 +			if(keycode != 0xff) {
   5.141 +				amikb_sendkey(keycode, ~keyflags & KF_BRK);
   5.142 +				printf("[%s] amiga key %xh\r\n", press ? "press" : "release", keycode);
   5.143  			} else {
   5.144 -				printf("%s: %x\r\n", keyflags & KF_BRK ? "release" : "press", (unsigned int)c);
   5.145 +				printf("[%s] no translation\r\n", press ? "press" : "release");
   5.146  			}
   5.147 -			keyflags = 0;
   5.148 +			keyflags &= ~KF_TRANSIENT;
   5.149  		}
   5.150  	}
   5.151  	return 0;
   5.152  }
   5.153  
   5.154 -void ps2write(unsigned char c)
   5.155 -{
   5.156 -	int i;
   5.157 -	unsigned short out = (unsigned short)c | ((unsigned short)(parity_even_bit(c) & 1) << 8);
   5.158  
   5.159 -	/* pull clock low for >60us */
   5.160 -	PS2LOW(BIT_CLK);
   5.161 -	_delay_us(60);
   5.162 -
   5.163 -	/* then pull data low and release clock */
   5.164 -	PS2LOW(BIT_DATA);
   5.165 -	PS2REL(BIT_CLK);
   5.166 -
   5.167 -	for(i=0; i<9; i++) {
   5.168 -		while(PINB & BIT_CLK);	/* wait for kbd to drive the clock low */
   5.169 -		PORTB |= out & 1;
   5.170 -		out >>= 1;
   5.171 -		while(!(PINB & BIT_CLK));	/* wait for kbd to drive the clock high */
   5.172 -	}
   5.173 -
   5.174 -	PS2REL(BIT_DATA);
   5.175 -	/* wait for ack */
   5.176 -	while(PINB & BIT_DATA);
   5.177 -	while(!(PINB & BIT_DATA));
   5.178 -}
   5.179 -
   5.180 -unsigned char ps2read(void)
   5.181 -{
   5.182 -	unsigned char key;
   5.183 -
   5.184 -	while(key_rd == key_wr) {
   5.185 -	}
   5.186 -
   5.187 -	cli();
   5.188 -	key = keybuf[key_rd];
   5.189 -	key_rd = NEXT_IDX(key_rd);
   5.190 -	sei();
   5.191 -
   5.192 -	return key;
   5.193 -}
   5.194 -
   5.195 -int ps2pending(void)
   5.196 -{
   5.197 -	return key_rd != key_wr;
   5.198 -}
   5.199 -
   5.200 -ISR(INT0_vect)
   5.201 -{
   5.202 -	static unsigned char value, valp, parity;
   5.203 -	static int nbits;
   5.204 -
   5.205 -	if(sending) {
   5.206 -	} else {
   5.207 -		if(nbits > 0 && nbits < 9) {
   5.208 -			value >>= 1;
   5.209 -			if(PINB & 1) {
   5.210 -				value |= 0x80;
   5.211 -				parity ^= 1;
   5.212 -			}
   5.213 -		}/* else if(nbits == 9) {
   5.214 -			valp = PINB & 1;
   5.215 -		}*/
   5.216 -		if(++nbits >= 11) {
   5.217 -			nbits = 0;
   5.218 -
   5.219 -			/* check parity */
   5.220 -			/*if((parity & 1) == (valp & 1)) {}*/
   5.221 -			keybuf[key_wr] = (unsigned char)value;
   5.222 -			key_wr = NEXT_IDX(key_wr);
   5.223 -
   5.224 -			value = 0;
   5.225 -			parity = 0;
   5.226 -		}
   5.227 -	}
   5.228 -}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/ps2kbd.c	Tue Oct 17 15:25:33 2017 +0300
     6.3 @@ -0,0 +1,92 @@
     6.4 +#include <avr/io.h>
     6.5 +#include <avr/interrupt.h>
     6.6 +#include <util/delay.h>
     6.7 +#include "ps2kbd.h"
     6.8 +#include "defs.h"
     6.9 +
    6.10 +#define BUF_SZ	16
    6.11 +#define BUF_IDX_MASK	(BUF_SZ - 1)
    6.12 +#define NEXT_IDX(x) (((x) + 1) & BUF_IDX_MASK)
    6.13 +static volatile unsigned char keybuf[BUF_SZ];
    6.14 +static volatile unsigned char key_rd, key_wr;
    6.15 +
    6.16 +static volatile int sending;
    6.17 +
    6.18 +void ps2write(unsigned char c)
    6.19 +{
    6.20 +#if 0
    6.21 +	int i;
    6.22 +	unsigned short out = (unsigned short)c | ((unsigned short)(parity_even_bit(c) & 1) << 8);
    6.23 +
    6.24 +	/* pull clock low for >60us */
    6.25 +	PS2LOW(BIT_CLK);
    6.26 +	_delay_us(60);
    6.27 +
    6.28 +	/* then pull data low and release clock */
    6.29 +	PS2LOW(BIT_DATA);
    6.30 +	PS2REL(BIT_CLK);
    6.31 +
    6.32 +	for(i=0; i<9; i++) {
    6.33 +		while(PINB & BIT_CLK);	/* wait for kbd to drive the clock low */
    6.34 +		PORTB |= out & 1;
    6.35 +		out >>= 1;
    6.36 +		while(!(PINB & BIT_CLK));	/* wait for kbd to drive the clock high */
    6.37 +	}
    6.38 +
    6.39 +	PS2REL(BIT_DATA);
    6.40 +	/* wait for ack */
    6.41 +	while(PINB & BIT_DATA);
    6.42 +	while(!(PINB & BIT_DATA));
    6.43 +#endif
    6.44 +}
    6.45 +
    6.46 +unsigned char ps2read(void)
    6.47 +{
    6.48 +	unsigned char key;
    6.49 +
    6.50 +	while(key_rd == key_wr) {
    6.51 +	}
    6.52 +
    6.53 +	cli();
    6.54 +	key = keybuf[key_rd];
    6.55 +	key_rd = NEXT_IDX(key_rd);
    6.56 +	sei();
    6.57 +
    6.58 +	return key;
    6.59 +}
    6.60 +
    6.61 +int ps2pending(void)
    6.62 +{
    6.63 +	return key_rd != key_wr;
    6.64 +}
    6.65 +
    6.66 +ISR(INT0_vect)
    6.67 +{
    6.68 +	static unsigned char value, parity;
    6.69 +	/*static unsigned char valp;*/
    6.70 +	static int nbits;
    6.71 +
    6.72 +	if(sending) {
    6.73 +	} else {
    6.74 +		if(nbits > 0 && nbits < 9) {
    6.75 +			value >>= 1;
    6.76 +			if(PIND & PDATA_BIT) {
    6.77 +				value |= 0x80;
    6.78 +				parity ^= 1;
    6.79 +			}
    6.80 +		}/* else if(nbits == 9) {
    6.81 +			valp = (PIND >> PDATA) & 1;
    6.82 +		}*/
    6.83 +		if(++nbits >= 11) {
    6.84 +			nbits = 0;
    6.85 +
    6.86 +			/* check parity */
    6.87 +			/*if((parity & 1) == (valp & 1)) {}*/
    6.88 +			keybuf[key_wr] = (unsigned char)value;
    6.89 +			key_wr = NEXT_IDX(key_wr);
    6.90 +
    6.91 +			value = 0;
    6.92 +			parity = 0;
    6.93 +		}
    6.94 +	}
    6.95 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/ps2kbd.h	Tue Oct 17 15:25:33 2017 +0300
     7.3 @@ -0,0 +1,8 @@
     7.4 +#ifndef PS2KBD_H_
     7.5 +#define PS2KBD_H_
     7.6 +
     7.7 +void ps2write(unsigned char c);
     7.8 +unsigned char ps2read(void);
     7.9 +int ps2pending(void);
    7.10 +
    7.11 +#endif	/* PS2KBD_H_ */
     8.1 --- a/src/scantbl.h	Sat Oct 14 07:23:47 2017 +0300
     8.2 +++ b/src/scantbl.h	Tue Oct 17 15:25:33 2017 +0300
     8.3 @@ -1,6 +1,7 @@
     8.4  #ifndef SCANTBL_H_
     8.5  #define SCANTBL_H_
     8.6  
     8.7 +/*
     8.8  enum {
     8.9  	KEY_ESC = 27,
    8.10  
    8.11 @@ -29,35 +30,21 @@
    8.12  	KEY_APPS,
    8.13  	KEY_ACPI_POWER, KEY_ACPI_SLEEP, KEY_ACPI_WAKEUP
    8.14  };
    8.15 -
    8.16 -
    8.17 -static const char *skeystr[] = {
    8.18 -	"F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", "F11", "F12",
    8.19 -	"SysRq", "Break", "Scroll Lock", "Caps Lock", "Num Lock",
    8.20 -	"L Shift", "R Shift", "L Ctrl", "R Ctrl", "L Alt", "R Alt", "L Win", "R Win", "Menu",
    8.21 -	"Insert", "Delete", "Home", "End", "Page Up", "Page Down", "Left", "Right", "Up", "Down",
    8.22 -	"Keypad 0", "Keypad 1", "Keypad 2", "Keypad 3", "Keypad 4", "Keypad 5", "Keypad 6",
    8.23 -	"Keypad 7", "Keypad 8", "Keypad 9", "Keypad /", "Keypad *", "Keypad -", "Keypad +",
    8.24 -	"Keypad .", "Keypad Enter",
    8.25 -	"WWW Search", "WWW Fav", "WWW Refresh", "WWW Stop", "WWW Fwd", "WWW Back", "WWW Home",
    8.26 -	"Prev", "Next", "Play", "Stop", "Volume Up", "Volume Down", "Mute", "Calculator",
    8.27 -	"My Computer", "Email", "Select Media", "Apps",
    8.28 -	"Power", "Sleep", "Wakeup",
    8.29 -};
    8.30 -
    8.31 +*/
    8.32  
    8.33  #define KEYMAP_NORMAL_SIZE	(sizeof keymap_normal / sizeof *keymap_normal)
    8.34 +#if 0
    8.35  static int keymap_normal[] = {
    8.36  	0, KEY_F9, 0, KEY_F5, KEY_F3, KEY_F1, KEY_F2, KEY_F12,	/* 00 - 07 */
    8.37  	0, KEY_F10, KEY_F8, KEY_F6,	KEY_F4, '\t', '`', 0,		/* 08 - 0f */
    8.38 -	0, KEY_LALT, KEY_LSHIFT, 0, KEY_LCTRL, 'q', '1', 0,		/* 10 - 17 */
    8.39 -	0, 0, 'z', 's', 'a', 'w', '2', 0,						/* 18 - 1f */
    8.40 -	0, 'c', 'x', 'd', 'e', '4', '3', 0,						/* 20 - 27 */
    8.41 -	0, ' ', 'v', 'f', 't', 'r', '5', 0,						/* 28 - 2f */
    8.42 -	0, 'n', 'b', 'h', 'g', 'y', '6', 0,						/* 30 - 37 */
    8.43 -	0, 0, 'm', 'j', 'u', '7', '8', 0,						/* 38 - 3f */
    8.44 -	0, ',', 'k', 'i', 'o', '0', '9', 0,						/* 40 - 47 */
    8.45 -	0, '.', '/', 'l', ';', 'p', '-', 0,						/* 48 - 4f */
    8.46 +	0, KEY_LALT, KEY_LSHIFT, 0, KEY_LCTRL, 'Q', '1', 0,		/* 10 - 17 */
    8.47 +	0, 0, 'Z', 'S', 'A', 'W', '2', 0,						/* 18 - 1f */
    8.48 +	0, 'C', 'X', 'D', 'E', '4', '3', 0,						/* 20 - 27 */
    8.49 +	0, ' ', 'V', 'F', 'T', 'R', '5', 0,						/* 28 - 2f */
    8.50 +	0, 'N', 'B', 'H', 'G', 'Y', '6', 0,						/* 30 - 37 */
    8.51 +	0, 0, 'M', 'J', 'U', '7', '8', 0,						/* 38 - 3f */
    8.52 +	0, ',', 'K', 'I', 'O', '0', '9', 0,						/* 40 - 47 */
    8.53 +	0, '.', '/', 'L', ';', 'P', '-', 0,						/* 48 - 4f */
    8.54  	0, 0, '\'', 0, '[', '=', 0, 0,							/* 50 - 57 */
    8.55  	KEY_CAPSLK, KEY_RSHIFT, '\n', ']', 0, '\\', 0, 0,		/* 58 - 5f */
    8.56  	0, 0, 0, 0, 0, 0, '\b', 0,								/* 60 - 67 */
    8.57 @@ -66,8 +53,35 @@
    8.58  	KEY_F11, KEY_KP_PLUS, KEY_KP_3, KEY_KP_MINUS, KEY_KP_MUL, KEY_KP_9, KEY_SCRLK, 0,/* 78 - 7f */
    8.59  	0, 0, 0, KEY_F7											/* 80 - 83 */
    8.60  };
    8.61 +#endif
    8.62 +
    8.63 +/* converts a normal (non-extended) PS/2 scancode to an amiga rawkey value
    8.64 + * caps lock -> control
    8.65 + * ctrl -> amiga
    8.66 + * F12 -> help
    8.67 + */
    8.68 +static unsigned char keymap_normal[] = {
    8.69 +	0xff, 0x58, 0xff, 0x54, 0x52, 0x50, 0x51, 0x5f,		/* 00 - 07: - f9 - f5 f3 f1 f2 f12 */
    8.70 +	0xff, 0x59, 0x57, 0x55, 0x53, 0x42, 0x00, 0xff,		/* 08 - 0f: - f10 f8 f6 f4 tab ` - */
    8.71 +	0xff, 0x64, 0x60, 0xff, 0x66, 0x10, 0x01, 0xff,		/* 10 - 17: - lalt lshift - lctrl(lamiga) Q 1 - */
    8.72 +	0xff, 0xff, 0x31, 0x21, 0x20, 0x11, 0x02, 0xff,		/* 18 - 1f: - - Z S A W 2 - */
    8.73 +	0xff, 0x33, 0x32, 0x22, 0x12, 0x04, 0x03, 0xff,		/* 20 - 27: - C X D E 4 3 - */
    8.74 +	0xff, 0x40, 0x34, 0x23, 0x14, 0x13, 0x05, 0xff,		/* 28 - 2f: - space V F T R 5 - */
    8.75 +	0xff, 0x36, 0x35, 0x25, 0x24, 0x15, 0x06, 0xff,		/* 30 - 37: - N B H G Y 6 - */
    8.76 +	0xff, 0xff, 0x37, 0x26, 0x16, 0x07, 0x08, 0xff,		/* 38 - 3f: - - M J U 7 8 - */
    8.77 +	0xff, 0x38, 0x27, 0x17, 0x18, 0x0a, 0x09, 0xff,		/* 40 - 47: - , K I O 0 9 - */
    8.78 +	0xff, 0x39, 0x3a, 0x28, 0x29, 0x19, 0x0b, 0xff,		/* 48 - 4f: - . / L ; P minus - */
    8.79 +	0xff, 0xff, 0x2a, 0xff, 0x1a, 0x0c, 0xff, 0xff,		/* 50 - 57: - - \ - [ = - - */
    8.80 +	0x63, 0x61, 0x44, 0x1b, 0xff, 0x0d, 0xff, 0xff,		/* 58 - 5f: caps rshift enter ] - \ - - */
    8.81 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x41, 0xff,		/* 60 - 67: - - - - - - backsp - */
    8.82 +	0xff, 0x1d, 0xff, 0x2d, 0x3d, 0xff, 0xff, 0xff,		/* 68 - 6f: - KP1 - KP4 KP7 - - - */
    8.83 +	0x0f, 0x3c, 0x1e, 0x2e, 0x2f, 0x3e, 0x45, 0x5a,		/* 70 - 77: KP0 KP. KP2 KP5 KP6 KP8 esc numlk */
    8.84 +	0xff, 0x5e, 0x1f, 0x4a, 0x5d, 0x3f, 0x5b, 0xff,		/* 78 - 7f: f11 KP+ KP3 KP- KP* KP9 scrlk - */
    8.85 +	0xff, 0xff, 0xff, 0x56								/* 80 - 83: - - - f7 */
    8.86 +};
    8.87  
    8.88  #define KEYMAP_EXT_SIZE	(sizeof keymap_ext / sizeof *keymap_ext)
    8.89 +#if 0
    8.90  static int keymap_ext[] = {
    8.91  	0, 0, 0, 0, 0, 0, 0, 0,									/* 00 - 07 */
    8.92  	0, 0, 0, 0, 0, 0, 0, 0,									/* 08 - 0f */
    8.93 @@ -77,11 +91,39 @@
    8.94  	KEY_MM_STOP, 0, 0, KEY_MM_CALC, 0, 0, 0, KEY_APPS,		/* 28 - 2f */
    8.95  	KEY_MM_WWW_FWD, 0, KEY_MM_VOLUP, 0, KEY_MM_PLAY, 0, 0, KEY_ACPI_POWER,	/* 30 - 37 */
    8.96  	KEY_MM_WWW_BACK, 0, KEY_MM_WWW_HOME, KEY_MM_STOP, 0, 0, 0, KEY_ACPI_SLEEP,	/* 38 - 3f */
    8.97 -	KEY_MM_MYCOMP, 0, 0, 0, KEY_MM_EMAIL, 0, KEY_KP_DIV, 0,	/* 40 - 47 */
    8.98 -	0, KEY_MM_NEXT, 0, 0, KEY_MM_SELECT, 0, 0, 0,			/* 48 - 4f */
    8.99 -	0, 0, KEY_ACPI_WAKEUP, 0, 0, KEY_END, 0, KEY_LEFT,		/* 50 - 57 */
   8.100 -	KEY_HOME, 0, 0, 0, KEY_INS, KEY_DEL, KEY_DOWN, 0,		/* 58 - 5f */
   8.101 -	KEY_RIGHT, KEY_UP, 0, 0, 0, 0, KEY_DOWN, 0,				/* 60 - 67 */
   8.102 +	KEY_MM_MYCOMP, 0, 0, 0, 0, 0, 0, 0,						/* 40 - 47 */
   8.103 +	KEY_MM_EMAIL, 0, KEY_KP_DIV, 0, 0, KEY_MM_NEXT, 0, 0,	/* 48 - 4f */
   8.104 +	KEY_MM_SELECT, 0, 0, 0, 0, 0, 0, 0,						/* 50 - 57 */
   8.105 +	0, 0, KEY_KP_ENTER, 0, 0, 0, KEY_ACPI_WAKEUP, 0,		/* 58 - 5f */
   8.106 +	0, 0, 0, 0, 0, 0, 0, 0,									/* 60 - 67 */
   8.107 +	0, KEY_END, 0, KEY_LEFT, KEY_HOME, 0, 0, 0,				/* 68 - 6f */
   8.108 +	KEY_INS, KEY_DEL, KEY_DOWN, 0, KEY_RIGHT, KEY_UP, 0, 0,	/* 70 - 77 */
   8.109 +	0, 0, KEY_PGDOWN, 0, 0, KEY_PGUP, 0, 0,					/* 78 - 7f */
   8.110 +};
   8.111 +#endif
   8.112 +
   8.113 +static unsigned char keymap_ext[] = {
   8.114 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 00 - 07: - - - - - - - - */
   8.115 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 08 - 0f: - - - - - - - - */
   8.116 +	0xff, 0x65, 0xff, 0xff, 0x67, 0xff, 0xff, 0xff,		/* 10 - 17: - ralt - - rctrl(ramiga) - - - */
   8.117 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x66,		/* 18 - 1f: - - - - - - - lwin(lamiga) */
   8.118 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x67,		/* 20 - 27: - - - - - - - rwin(ramiga) */
   8.119 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 28 - 2f */
   8.120 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 30 - 37 */
   8.121 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 38 - 3f */
   8.122 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 40 - 47 */
   8.123 +	0xff, 0xff, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 48 - 4f: - - KP/ - - - - - */
   8.124 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 50 - 57 */
   8.125 +	0xff, 0xff, 0x43, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 58 - 5f: - - KP_enter - - - - - */
   8.126 +	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,		/* 60 - 67 */
   8.127 +	0xff, 0x1d, 0xff, 0x4f, 0x3d, 0xff, 0xff, 0xff,		/* 68 - 6f: - end - left home - - - */
   8.128 +	0x0f, 0x46, 0x4d, 0xff, 0x4e, 0x4c, 0xff, 0xff,		/* 70 - 77: ins del down - right up - - */
   8.129 +	0xff, 0xff, 0x1f, 0xff, 0xff, 0x3f, 0xff, 0xff		/* 78 - 7f: - - pgdown - - pgup - - */
   8.130  };
   8.131  
   8.132 +/* some useful keycodes */
   8.133 +#define AMIKEY_CTRL		0x63
   8.134 +#define AMIKEY_LAMI		0x66
   8.135 +#define AMIKEY_RAMI		0x67
   8.136 +
   8.137  #endif	/* SCANTBL_H_ */
     9.1 --- a/src/serial.c	Sat Oct 14 07:23:47 2017 +0300
     9.2 +++ b/src/serial.c	Tue Oct 17 15:25:33 2017 +0300
     9.3 @@ -1,11 +1,11 @@
     9.4 +#ifndef F_CPU
     9.5  #ifdef XTAL
     9.6 -#define F_CLK	XTAL
     9.7  #define F_CPU	XTAL
     9.8  #else
     9.9  #warning "compiled for 1mhz internal rc osc. serial comms won't work"
    9.10 -#define F_CLK	1000000
    9.11  #define F_CPU	1000000
    9.12  #endif
    9.13 +#endif
    9.14  
    9.15  #include <stdio.h>
    9.16  #include <avr/io.h>
    9.17 @@ -30,7 +30,7 @@
    9.18  
    9.19  void init_serial(long baud)
    9.20  {
    9.21 -	unsigned int ubrr_val = F_CLK / 16 / baud - 1;
    9.22 +	unsigned int ubrr_val = F_CPU / 16 / baud - 1;
    9.23  
    9.24  	power_usart0_enable();
    9.25  
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/src/timer.c	Tue Oct 17 15:25:33 2017 +0300
    10.3 @@ -0,0 +1,35 @@
    10.4 +#include <avr/io.h>
    10.5 +#include <avr/interrupt.h>
    10.6 +#include <avr/power.h>
    10.7 +#include "timer.h"
    10.8 +
    10.9 +#define PRESCL_256	4
   10.10 +/* 256 ticks per interrupt, 256 clock divisor */
   10.11 +#define TICKS_PER_SEC	(F_CPU / 256 / 256)
   10.12 +
   10.13 +static volatile unsigned long ticks;
   10.14 +
   10.15 +void init_timer(void)
   10.16 +{
   10.17 +	power_timer0_enable();
   10.18 +
   10.19 +	TCCR0A = 0;
   10.20 +	TCCR0B = PRESCL_256;
   10.21 +
   10.22 +	TIMSK0 |= (1 << TOIE0);	/* enable ovf intr. */
   10.23 +}
   10.24 +
   10.25 +void reset_timer(void)
   10.26 +{
   10.27 +	ticks = 0;
   10.28 +}
   10.29 +
   10.30 +unsigned long get_msec(void)
   10.31 +{
   10.32 +	return 1000 * ticks / TICKS_PER_SEC;
   10.33 +}
   10.34 +
   10.35 +ISR(TIMER0_OVF_vect)
   10.36 +{
   10.37 +	++ticks;
   10.38 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/src/timer.h	Tue Oct 17 15:25:33 2017 +0300
    11.3 @@ -0,0 +1,8 @@
    11.4 +#ifndef TIMER_H_
    11.5 +#define TIMER_H_
    11.6 +
    11.7 +void init_timer(void);
    11.8 +void reset_timer(void);
    11.9 +unsigned long get_msec(void);
   11.10 +
   11.11 +#endif	/* TIMER_H_ */